入门教程:实例详解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. ASP.NET面试题130道

     130道ASP.NET面试题 1. 简述 private. protected. public. internal 修饰符的访问权限. 答 . private : 私有成员, 在类的内部才可以访问. ...

  2. 深入理解JVM(二)--对象的创建

    Java是一门面向对象的语言,在Java程序运行的过程中,无时无刻都会有对象被创建出来,在程序语言中,创建对象(例如克隆,反序列化)通常仅仅是一个new关键字,但是在虚拟机中是怎样的呢?本文主要了解一 ...

  3. GIt三剑客

    一. Github 什么是Github? github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开. Github 由Chris Wan ...

  4. 【转载】Sqlserver在创建表的时候如何定义自增量Id

    在Sqlserver创建表的过程中,有时候需要为表指定一个自增量Id,其实Sqlserver和Mysql等数据库都支持设置自增量Id字段,允许设置自增量Id的标识种子和标识自增量,标识种子代表初始自增 ...

  5. 使用企业证书给iOS应用重签

    来源:https://github.com/sailtsao/iReSign 这里有个开源的签名工具,已经修改为支持dylib frameworks等的签名了,使用这个签名不会出现任何问题 iReSi ...

  6. hybris commerce storefront的产品搜索功能

    在Hybris Commerce Cloud的storefront的搜索栏键入一些字母,每次键入,会触发一个发送到后台的http请求实现live search的功能: http url如下:https ...

  7. ISCC之RE_REV02

    打开IDA,跟着主函数转了一圈,无果,但是在下面翻到一串base64 base64解码,发现被坑了 this_is_not_the_flag_you_seek_keep_looking 继续翻,发现这 ...

  8. 转 C#关于DateTime得到的当前时间的格式和用法

    DateTime.Now.ToShortTimeString() DateTime dt = DateTime.Now; dt.ToString();//2005-11-5 13:21:25 dt.T ...

  9. (java)selenium webdriver学习--通过id、name定位,输入内容,搜索,关闭操作、通过tagname查找元素

    selenium webdriver学习--通过id.name定位,输入内容,搜索,关闭操作:通过tagname查找元素 打开谷歌浏览器,输入不同的网站,搜索框的定位含有不同元素(有时为id,有时为n ...

  10. C#向数据库中插入或更新null空值

    一.在SQL语句中直接插入null或空字符串“” int? item = null; item == null ? "null" : item.ToString(); item = ...