实例详解C++友元

在说明什么是友元之前,我们先说明一下为什么需要友元与友元的缺点:

  通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都生命成为public(共用的),然而这做带来的问题遍是任何外部函数都可以毫无约束的访问它操作它,c++利用friend修饰符,可以让一些你设定的函数能够对这些保护数据进行操作,避免把类成员全部设置成public,最大限度的保护数据成员的安全。友元能够使得普通函数直接访问类的保护数据,避免了类成员函数的频繁调用,可以节约处理器开销,提高程序的效率,但矛盾的是,即使是最大限度的保护,同样也破坏了类的封装特性,这即是友元的缺点,在现在cpu速度越来越快的今天我们并不推荐使用它,但它作为c++一个必要的知识点,一个完整的组成部分,我们还是需要讨论一下的。 
在类里声明一个普通函数,在前面加上friend修饰,那么这个函数就成了该类的友元,可以访问该类的一切成员。 .

下面我们来看一段代码,看看我们是如何利用友元来访问类的一切成员的。

 

#include <iostream>    
using namespace std;  
class Internet    
{    
public:    
    Internet(
char *name,char *address)    
    
{    
        strcpy(Internet::name,name);    
        strcpy(Internet::address,address);     
    }
  
friend 
void ShowN(Internet &obj);//友元函数的声明  
public:    
    
char name[20];  
    
char address[20];  
}
;  
  
  
void ShowN(Internet &obj)//函数定义,不能写成,void Internet::ShowN(Internet &obj)  
{  
    cout
<<obj.name<<endl;  
}
  
void main()    
{  
    Internet a(
"中国软件开发实验室","www.cndev-lab.com");  
    ShowN(a);  
    cin.
get();  
}
 

上面的代码通过友元函数的定义,我们成功的访问到了a对象的保护成员name,友元函数并不能看做是类的成员函数,它只是个被声明为类友元的普通函数,所以在类外部函数的定义部分不能够写成void Internet::ShowN(Internet &obj),这一点要注意。

一个普通函数可以是多个类的友元函数,对上面的代码我们进行修改,注意观察变化:

 

#include <iostream>    
using namespace std;  
class Country;  
class Internet    
{    
public:    
    Internet(
char *name,char *address)    
    
{    
        strcpy(Internet::name,name);    
        strcpy(Internet::address,address);     
    }
  
friend 
void ShowN(Internet &obj,Country &cn);//注意这里  
public:    
    
char name[20];  
    
char address[20];  
}
;  
  
class Country  
{  
public:  
    Country()  
    
{  
        strcpy(cname,
"中国");  
    }
  
friend 
void ShowN(Internet &obj,Country &cn);//注意这里  
protected:  
    
char cname[30];  
}
;  
  
void ShowN(Internet &obj,Country &cn)  
{  
    cout
<<cn.cname<<"|"<<obj.name<<endl;  
}
  
void main()    
{  
    Internet a(
"中国软件开发实验室","www.cndev-lab.com");  
    Country b;  
    ShowN(a,b);  
    cin.
get();  
}

一个类的成员函数函数也可以是另一个类的友元从而可以使得一个类的成员函数可以操作另一个类的数据成员,我们在下面的代码中增加一类Country,注意观察:

 

#include <iostream>    
using namespace std;  
class Internet;  
  
class Country  
{  
public:  
    Country()  
    
{  
        strcpy(cname,
"中国");  
    }
  
    
void Editurl(Internet &temp);//成员函数的声明  
protected:  
    
char cname[30];  
}
;  
class Internet  
{    
public:    
    Internet(
char *name,char *address)    
    
{    
        strcpy(Internet::name,name);    
        strcpy(Internet::address,address);   
    }
  
    friend 
void Country::Editurl(Internet &temp);//友元函数的声明  
protected:    
    
char name[20];  
    
char address[20];  
}
;  
void Country::Editurl(Internet &temp)//成员函数的外部定义  
{  
    strcpy(temp.address,
"edu.cndev-lab.com");  
    cout
<<temp.name<<"|"<<temp.address<<endl;  
}
  
void main()  
{  
    Internet a(
"中国软件开发实验室","www.cndev-lab.com");  
    Country b;  
    b.Editurl(a);  
    cin.
get();  
}

整个类也可以是另一个类的友元,该友元也可以称做为友类。友类的每个成员函数都可以访问另一个类的所有成员。

 

#include <iostream>    
using namespace std;  
class Internet;  
  
class Country  
{  
public:  
    Country()  
    
{  
        strcpy(cname,
"中国");  
    }
  
    friend 
class Internet;//友类的声明  
protected:  
    
char cname[30];  
}
;  
class Internet  
{  
public:    
    Internet(
char *name,char *address)    
    
{    
        strcpy(Internet::name,name);    
        strcpy(Internet::address,address);   
    }
  
    
void Editcname(Country &temp);  
protected:    
    
char name[20];  
    
char address[20];  
}
;  
void Internet::Editcname(Country &temp)  
{  
    strcpy(temp.cname,
"中华人民共和国");   
}
  
void main()  
{  
    Internet a(
"中国软件开发实验室","www.cndev-lab.com");  
    Country b;  
    a.Editcname(b);  
    cin.
get();  
}
在上面的代码中我们成功的通过Internet类Editcname成员函数操作了Country类的保护成员cname。

  在编程中,我们使用友元的另外一个重要原因是为了方便重载操作符的使用,这些内容我们将在后面的教程着重讨论!
55套 土木工程教学楼,实验楼毕业设计(包括设计图纸+计算书+论文文档资料):2841平米,四层中学教学楼(计算书、施组、建筑、结构图).zip3200平米四层职教教学楼(计算书、建筑、结构图).zip3264平米,三层框架教学楼毕业设计(计算书、建筑、结构图).zip3458平米四层活动中心科技楼(计算书、建筑、结构图).zip3725平米,四层培训中心教学楼(计算书、建筑、结构图).zip3965平米,三层框架教学楼毕业设计(计算书、施组、工程量计算、建筑、结构图).zip3969平米四层局部三层教学楼(电算、建筑、结构图、答辩PPT).zip4019平米,四层框架中学教学楼毕业设计(计算书、建筑、结构图).zip4184平米,三层框架教学楼(计算书、施组、部分建筑、结构图).zip4340.75平米,局部五层框架教学楼毕业设计(含计算书,建筑、结构图).zip4371.84平米,四层中学教学楼框架结构(计算书、建筑、结构图).zip4426平米,五层框架教学楼(开题报告、计算书、建筑、结构图).zip4665平米五层教学楼毕业设计(计算书、建筑、结构图).zip4823平米,四层实验楼(计算书、建筑、结构图).zip4层局部3层幼儿园,2315.97平米(计算书、建筑、结构图).zip5185平米五层框架教学楼(计算书、部分建筑、结构图、计算简图).zip5247平米,四层教学楼(计算书、PKPM模型、建筑图、部分结构图).zip5524平米六层带架空层中学教学楼(计算书、实习报告、建筑、结构图).zip5526平米,五层中学教学楼(计算书、施组、建筑、结构图).zip5532平米,四层框架教学楼毕业设计(计算书、部分建筑结构图).zip5627.7平米,五层中学教学楼(含计算书、部分建筑图).zip5880平米,五层教学楼(计算书、建筑、结构图).zip5层4200平米中学教学楼(计算书、施组、建筑、结构图).zip5层实验楼,总建筑面积6760㎡(计算书、建筑、结构图、PKPM计算文件).zip5层高校教学楼毕业设计(计算书、部分结构图).zip5层,2000平米左右框架高中教学楼毕业设计(计算书、建筑、结构图).zip6062平米,7层框架教学楼(计算书、建筑、结构图、中英文翻译).zip6196平米五层中学教学楼(计算书、建筑、结构图).zip6244.52平米,局部五层辅助教学楼(计算书、建筑、结构图).zip6294平米五层框架中学教学楼(计算书、部分建筑、结构图).zip6447.74平米,五层框架高中教学楼(计算书、建筑、结构图).zip6745平米,四层框架教学楼毕业设计(计算书、建筑结构图、毕业答辩PPT).zip6812平米五层高职教学楼(计算书、部分建筑、结构图).zip6层框架凹字形教学楼毕业设计(计算文件、部分建筑、结构图).zip6层,5283平米框架教学楼毕业设计(计算书、建筑、结构图).zip7144平米,五层局部三层技工实验楼(计算书、部分建筑结构图).zip7567平米五层局部四层职业学院教学楼(计算书、建筑、结构图).zip8层,11305.82平米大学实验楼(计算书、部分建筑、结构图).zip局部6层特警训练大楼5523平米(计算书、建筑、结构图).zip局部6层,2868平米教学楼毕业设计(计算书、建筑、结构图).zip总建筑面积为3773.6平米,5层教学楼(计算书、建筑、结构图).zip某3层教学楼全套设计(4184平,含计算书,建筑图、结构图,施工组织设计).zip某3层教学楼全套设计(约4000平,含计算书,建筑图,结构图,施工组织设计,工程量计算书).zip某4层中学教学楼全套设计(2700平左右,含计算书,建筑图,结构图).zip某4层中学教学楼全套设计(2726.4平,含任务书,计算书,建筑图, 结构图).zip某4层中学教学楼全套设计(含计算书,建筑图、结构图).zip某4层教学楼全套设计(5000平左右,含任务书,开题报告,计算书,建筑图,结构图,外文翻译).zip某4层教学楼全套设计(7050平,含任务书,计算书,建筑图,结构图).zip某4层教学楼全套设计(7258平,含计算书,建筑图,结构图).zip某4层框架教学楼全套设计(6800平,含计算书,建筑图,结构图,毕业答辩PPT).zip某5层中学教学楼全套设计 (4340平,含计算书,建筑、结构图).zip某5层教学楼全套设计 (4665平,含计算书、建筑图,结构图).zip某6层中学教学楼设计(含任务书,开题报告,实习报告,计算书,建筑图,结构图).zip某6层教学楼全套设计(含计算书、建筑
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值