入门教程:实例详解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. java 正则和连接json

    前面已经写了不少关于C# 怎么使用正则,有兴趣,可以翻译成java代码. 以图片为例子: import java.util.regex.Matcher; import java.util.regex. ...

  2. docker第一章--介绍和安装

  3. C# 将Excel导出PDF

    1.安装所需包,使用nuget安装所需包 1.1.Spire.Xls 1.2.iTextSharp.text.pdf 2.Spire.Xls介绍 将Excel转换为PDF是一个很常用的功能,常见的转换 ...

  4. SuperTab

    Tab快捷键提示功能 下载 http://www.vim.org/scripts/script.php?script_id=1643 安装 # vi supertab.vmb : UseVimball ...

  5. Android多线程操作,as快捷键笔记

    Android studio 快捷键 cmd+p 快速查看该方法的参数定义 * * option + shift +上下 快速移动上下行 * * cmd + e 显示最近操作的文件 * * cmd + ...

  6. ConcurrentLinkedQueue (一)

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

  7. Django异常 - ImportError: No module named django.core.management

    Django错误 - ImportError: No module named django.core.management问题描述:在命令行输入 manage.py runserver,提示找不到d ...

  8. vue $refs操作DOM

    原文链接:https://www.cnblogs.com/xumqfaith/p/7743387.html 如图,ref 被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs 对象 ...

  9. mysql学习之基础篇01

    大概在一周前看了燕十八老师讲解的mysql数据库视频,也跟着学了一周,我就想把我这一周所学的知识跟大家分享一下:因为是第一次写博客,所以可能会写的很烂,请大家多多包涵.文章中有不对的地方还请大家指出来 ...

  10. django配置*app*登录案例*orm简用

    1.静态文件的配置和使用 1.静态文件的配置和使用 没有css样式: 添加样式 结果: <html lang="en"> <head> <meta c ...