入门教程:实例详解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. lombok使用教程

    Lombok介绍.使用方法和总结https://www.cnblogs.com/heyonggang/p/8638374.html Lombok简介.使用.工作原理.优缺点https://www.ji ...

  2. CCF 2016-04-2 俄罗斯方块

    CCF 2016-04-2 俄罗斯方块 题目 问题描述 俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游戏. 游戏在一个15行10列的方格图上进行,方格图上的每一个格子可能已经放置了方块,或者 ...

  3. DuplexChannel

    [ServiceContract(Namespace = "http://xx.com", CallbackContract = typeof(Ipub_c))] public i ...

  4. Fortify漏洞之Dynamic Code Evaluation: Code Injection(动态脚本注入)和 Password Management: Hardcoded Password(密码硬编码)

    继续对Fortify的漏洞进行总结,本篇主要针对  Dynamic Code Evaluation: Code Injection(动态脚本注入) 和 Password Management: Har ...

  5. python多进程间通信

    这里使用pipe代码如下: import time from multiprocessing import Process import multiprocessing class D: @stati ...

  6. p1.BTC-密码学的原理

    所谓加密货币是不加密的,区块链上所有的交易内容(包括:账户的地址,转账的地址)都是公开的. Bitcoin中主要用到密码学的中的两个功能:Hash和签名. 一 Hash Cryptographic h ...

  7. mac中git flow使用

    初始化 git flow init   最后就一路回车选择默认的就ok了 常用命令以及分支:分支介绍:1.master.只有一个,并且不会在master上进行代码的操作.2.develop.只有一个, ...

  8. array_pop

    array_pop() 函数删除数组中的最后一个元素,返回数组的最后一个值.如果数组是空的,或者非数组,将返回 NULL. <?php$a=["red","gree ...

  9. 分配swap分区空间

    1. 分区,并修改为swap分区ID [root@centos2 ~]# fdisk /dev/sdb 欢迎使用 fdisk (util-linux ). 更改将停留在内存中,直到您决定将更改写入磁盘 ...

  10. 批处理引擎MapReduce内部原理

    批处理引擎MapReduce内部原理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MapReduce作业生命周期 MapReduce作业作为一种分布式应用程序,可直接运行在H ...