入门教程:实例详解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。

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

 
 

《挑战30天C++入门极限》入门教程:实例详解C++友元的更多相关文章

  1. 05-Vue入门系列之Vue实例详解与生命周期

    Vue的实例是Vue框架的入口,其实也就是前端的ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进行对整个Vue实例生成.编译.挂着. ...

  2. 【转】Zabbix 3.0 从入门到精通(zabbix使用详解)

    [转]Zabbix 3.0 从入门到精通(zabbix使用详解) 第1章 zabbix监控 1.1 为什么要监控 在需要的时刻,提前提醒我们服务器出问题了 当出问题之后,可以找到问题的根源   网站/ ...

  3. Java web 入门知识 及HTTP协议详解

     Java  web  入门知识 及HTTP协议详解 WEB入门 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资 ...

  4. Farseer.net轻量级开源框架 入门篇:添加数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 分类逻辑层 下一篇:Farseer.net轻量级开源框架 入门篇: 修改数据详解 ...

  5. Farseer.net轻量级开源框架 入门篇:修改数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 添加数据详解 下一篇:Farseer.net轻量级开源框架 入门篇: 删除数据详解 ...

  6. Farseer.net轻量级开源框架 入门篇:删除数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 修改数据详解 下一篇:Farseer.net轻量级开源框架 入门篇: 查询数据详解 ...

  7. Farseer.net轻量级开源框架 入门篇:查询数据详解

    导航 目   录:Farseer.net轻量级开源框架 目录 上一篇:Farseer.net轻量级开源框架 入门篇: 删除数据详解 下一篇:Farseer.net轻量级开源框架 中级篇: Where条 ...

  8. UWP入门(七)--SplitView详解与页面跳转

    原文:UWP入门(七)--SplitView详解与页面跳转 官方文档,逼着自己用英文看,UWP开发离不开官方文档 1. SplitView 拆分视图控件 拆分视图控件具有一个可展开/可折叠的窗格和一个 ...

  9. Linux计划任务Crontab实例详解教程

    说明:Crontab是Linux系统中在固定时间执行某一个程序的工具,类似于Windows系统中的任务计划程序 下面通过详细实例来说明在Linux系统中如何使用Crontab 操作系统:CentOS ...

随机推荐

  1. Online Hard Example Mining 理解

    Definition: Online Hard Example Mining (OHEM) is a way to pick hard examples with reduced computatio ...

  2. 记一次在 Get 请求参数为 Null 值的折腾

    先说主要原因,是因为一个 NgZerro 的 Select 组件,需要显示 placeHolder 文字,初始值为 null,然后直接绑定到查询参数中,传输到后端导致 BadRequest,参数解析失 ...

  3. C#_WPF中创建二维码、识别二维码

    第三方库: WPFMediaKit.dll (WPFMediaKit摄像头处理) zing.dll NuGet安装这两个第三方dll 项目截图预览: 项目代码: using System; using ...

  4. [转]关于ORA-00979 不是 GROUP BY 表达式错误的解释

    转自:https://www.cnblogs.com/vigarbuaa/archive/2012/06/25/2561225.html ORA-00979 不是 GROUP BY 表达式”这个错误, ...

  5. ios开发之NSData

    NSData用于保存字节数组. 初始化 - (instancetype)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length free ...

  6. ConcurrentLinkedQueue (一)

    ConcurrentLinkedQueue 主要讲一下在JDK8中,ConcurrentLikedQueue是如何入队,出队的. 首先我们要明白,ConcurrentLikedQueue是一种安全的没 ...

  7. mysql Starting MySQL..The server quit without updating PID file

    可能的原因和解决办法 1.可能是/usr/local/mysql/data/rekfan.pid文件没有写的权限解决方法 :给予权限,执行 chown -R mysql:mysql /var/data ...

  8. 资源管理与调度系统-YARN的资源调度器

    资源管理与调度系统-YARN的资源调度器 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 资源调度器是Hadoop YARN中最核心的组件之一,它是ResourceManager中的 ...

  9. IDG资本

    https://baike.baidu.com/item/IDG/10412 美国国际数据集团(International Data Group) 是全世界最大的信息技术出版.研究.发展与风险投资公司 ...

  10. springboot集成redis 附redis基本操作类

    1 pom.xml添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifac ...