首页
学习
活动
专区
圈层
工具
发布
30 篇文章
1
《挑战30天C++入门极限》C++的iostream标准库介绍(1)
2
《挑战30天C++入门极限》C++的iostream标准库介绍(2)
3
《挑战30天C++入门极限》C++的iostream标准库介绍(3)
4
《挑战30天C++入门极限》C++运算符重载赋值运算符
5
《挑战30天C++入门极限》C++运算符重载函数基础及其值返回状态
6
《挑战30天C++入门极限》对C++递增(增量)运算符重载的思考
7
《挑战30天C++入门极限》类的分解,抽象类与纯虚函数的需要性
8
《挑战30天C++入门极限》C++中利用构造函数与无名对象简化运算符重载函数
9
《挑战30天C++入门极限》C++中类的多态与虚函数的使用
10
《挑战30天C++入门极限》C++运算符重载转换运算符
11
《挑战30天C++入门极限》图例实解:C++中类的继承特性
12
《挑战30天C++入门极限》C++类的继承与多重继承的访问控制
13
《挑战30天C++入门极限》图文例解C++类的多重继承与虚拟继承
14
《挑战30天C++入门极限》理解C++面向对象程序设计中的抽象理论
15
《挑战30天C++入门极限》C++面向对象编程入门:构造函数与析构函数
16
《挑战30天C++入门极限》C++类对象的复制-拷贝构造函数
17
《挑战30天C++入门极限》C++类静态数据成员与类静态成员函数
18
《挑战30天C++入门极限》入门教程:实例详解C++友元
19
《挑战30天C++入门极限》C++面向对象编程入门:类(class)
20
《挑战30天C++入门极限》新手入门:C++中的函数重载
21
《挑战30天C++入门极限》新手入门:C/C++中的结构体
22
《挑战30天C++入门极限》C/C++中字符串常量的不相等性及字符串的Copy
23
《挑战30天C++入门极限》新手入门:C++中堆内存(heap)的概念和操作方法
24
《挑战30天C++入门极限》C/C++中字符指针数组及指向指针的指针的含义
25
《挑战30天C++入门极限》C/C++中结构体(struct)知识点强化
26
《挑战30天C++入门极限》新手入门:关于C++中的内联函数(inline)
27
《挑战30天C++入门极限》新手入门:C/C++中枚举类型(enum)
28
《挑战30天C++入门极限》新手入门:C++中布尔类型
29
《挑战30天C++入门极限》新手入门:C/C++中数组和指针类型的关系
30
《挑战30天C++入门极限》新手入门:C++下的引用类型

《挑战30天C++入门极限》入门教程:实例详解C++友元

代码语言:javascript
复制






 

入门教程:实例详解C++友元

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

  通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都生命成为public(共用的),然而这做带来的问题遍是任何外部函数都可以毫无约束的访问它操作它,c++利用friend修饰符,可以让一些你设定的函数能够对这些保护数据进行操作,避免把类成员全部设置成public,最大限度的保护数据成员的安全。 


  友元能够使得普通函数直接访问类的保护数据,避免了类成员函数的频繁调用,可以节约处理器开销,提高程序的效率,但矛盾的是,即使是最大限度的保护,同样也破坏了类的封装特性,这即是友元的缺点,在现在cpu速度越来越快的今天我们并不推荐使用它,但它作为c++一个必要的知识点,一个完整的组成部分,我们还是需要讨论一下的。 


  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。 


  在编程中,我们使用友元的另外一个重要原因是为了方便重载操作符的使用,这些内容我们将在后面的教程着重讨论!




 




 











下一篇
举报
领券