在网上看到的文章, 写的挺全的,  具有总结性质. 于是转过来了..

源地址(呵呵, 他也是转的)http://www.cnblogs.com/skyczw/archive/2008/05/27/1208194.html

《windows环境多线程编程原理与应用》中解释: 如果将类的封装比喻成一堵墙的话,那么友元机制就像墙上了开了一个门,那些得 到允许的类或函数允许通过这个门访问一般的类或者函数无法访问的私有属性和方法。友元机制使类的封装性得到消弱,所以使用时一定要慎重。友元类的说明将外界的某个类在本类别的定义中说明为友元,那么外界的类就成为本类的“朋 友”,那个类就可以访问本类的私有数据了。

class Merchant
{
private :
    int m_MyMoney;
    int m_MyRoom;
    … …
public:
    Friend class Lawyer;
    Int getmoney();
    … …
};

class Lawyer
{
private:
    … …
public:
    … …
};

只有你赋予某个类为你的友元时,那个类才有访问你的私有数据的权利。
说明一个函数为一个类的友元函数则该函数可以访问此类的私有数据和方法。定义方法是在类的定义中,在函数名前加上关键字friend.

《挑战30天C/C++》这样解释:
在说明什么是友元之前,我们先说明一下为什么需要友元与友元的缺点:
通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都生命成为public(共用的),然而这做带来的问题遍是任何外部函数都可以毫无约束的访问它操作它,c++利用friend修饰符,可以让一些你设定的函数能够对这些保护数据进行操作,避免把类成员全部设置成public,最大限度的保护数据成员的安全。友元能够使得普通函数直接访问类的保护数据,避免了类成员函数的频繁调用,可以节约处理器开销,提高程序的效率,但所矛盾的是,即使是最大限度大保护,同样也破坏了类的封装特性,这即是友元的缺点,在现在cpu速度越来越快的今天我们并不推荐使用它,但它作为c++一个必要的知识点,一个完整的组成部分,我们还是需要讨论一下的。在类里声明一个普通数学,在前面加上friend修饰,那么这个函数就成了该类的友元,可以访问该类的一切成员。
下面我们来看一段代码,看看我们是如何利用友元来访问类的一切成员的

//程序作者:管宁
//站点:www.cndev-lab.com
//所有稿件均有版权,如要转载,请务必著名出处和作者
#include <iostream>
using namespace std;
class Internet
{
public:
    Internet(char *name,char *address)   // 改为:internet(const char *name , const char *address)
    {
        strcpy(Internet::name,name);
        strcpy(Internet::address,address);
    }
    friend void ShowN(Internet &obj);   //友元函数的声明
public:              // 改为:private
    char name[20];
    char address[20];
};
void ShowN(Internet &obj)        //函数定义,不能写成,void Internet::ShowN(Internet &obj)
{
    cout<<obj.name<<endl;          //可访问internet类中的成员
}
void main()
{
    Internet a("中国软件开发实验室","www.cndev-lab.com");
    ShowN(a);
    cin.get();
}

上面的代码通过友元函数的定义,我们成功的访问到了a对象的保护成员name,友元函数并不能看做是类的成员函数,它只是个被声明为类友元的普通函数,所以在类外部函数的定义部分不能够写成void Internet::ShowN(Internet &obj),这一点要注意。

一个普通函数可以是多个类的友元函数,对上面的代码我们进行修改,注意观察变化:

//程序作者:管宁
//站点:www.cndev-lab.com
//所有稿件均有版权,如要转载,请务必著名出处和作者
#include <iostream>
using namespace std;
class Country;
class Internet
{
public:
    Internet(char *name,char *address)        // 改为:internet(const char *name , const 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,注意观察

//程序作者:管宁
//站点:www.cndev-lab.com
//所有稿件均有版权,如要转载,请务必著名出处和作者
#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();
}

整个类也可以是另一个类的友元,该友元也可以称做为友类。友类的每个成员函数都可以访问另一个类的所有成员

//程序作者:管宁
//站点:www.cndev-lab.com
//所有稿件均有版权,如要转载,请务必著名出处和作者

#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();
}

转载于:https://www.cnblogs.com/kupig/archive/2011/10/11/2206847.html

C++总结 友元类和友元函数相关推荐

  1. 【C++ 基础篇:21】:friend 友元四连问:什么是友元?友元类?友元函数?什么时候用友元?

    本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段:基础篇.STL 篇.高阶数据结构与算法篇,相关重点内容如下: 基础篇:类与对象(涉及C++的三大特 ...

  2. 友元实例:友元类及友元函数

    学习了c++这么久,一直没有对友元进行了解,据说友元不是特别好用(据说,不是我说的),因此直到今天才去了解.其实友元确实不是很常用,但友元功能确实很实用,它不但能够释放类中的非公有成员,同时还能保证了 ...

  3. C++友元:友元函数、友元类和友元成员函数

    Table of Contents 1.友元函数 2.友元类 3.友元成员函数 友元小结: 参考资料: 有些情况下,允许特定的非成员函数访问一个类的私有成员,同时仍阻止一般的访问,这是很方便做到的.例 ...

  4. C++友元类和友元函数

    特点: 能访问私有成员 破坏封装性 友元关系不可传递.若B是A的友元,C是B的友元,但C不一定是A的友元,要看类中是否有申明. 友元关系的单向性.若A是B的友元,但B不一定是A的友元,要看类中是否申明 ...

  5. Th3.9:友元函数、友元类、友元成员函数详述

     本博客将记录:类的相关知识点的第9节的笔记! (这个在学习C++基础课程时已经学习过一次了,这里再次简单地回顾一下而已) 今天总结的知识分为以下3个点:   一.友元函数(对于非成员函数而言)   ...

  6. java友元类_友元实例:友元类及友元函数

    学习了c++这么久,一直没有对友元进行了解,据说友元不是特别好用(据说,不是我说的),因此直到今天才去了解.其实友元确实不是很常用,但友元功能确实很实用,它不但能够释放类中的非公有成员,同时还能保证了 ...

  7. java中友元类_友元类成员的依赖关系|循环依赖

    定义一个CBottle类,另一个类CCarton的某个成员对CBottle进行操作,因此在CBottle类中赋予CCarton成员的友元权利.我们很容易写出如下代码: //CBottle类的头文件 b ...

  8. java友元类_C++友元(Friend)用法实例简介

    相对于Java而言,友元是C++中特有的一种元素,很多教材上对其介绍的相对较少,因此初学的时候往往不能很快掌握,本文总结了友元的用法和一些注意的地方,供大家参考借鉴.希望能对初学C++的朋友起到一点帮 ...

  9. C++friend 友元类和友元函数

    •能访问私有成员 •破坏封装性 •友元关系不可传递 •友元关系的单向性 •友元声明的形式及数量不受限制

最新文章

  1. php7 $this-,在PHP中如何为匿名函数指定this?
  2. 装箱问题C语言报告,装包装箱问题 (C语言代码)
  3. SAML简介:安全地共享数字身份信息
  4. Laravel源码解析之ENV配置
  5. Java I/O体系之Writer和Reader详细讲解
  6. 使用CRT调试功能来检测内存泄漏
  7. 第10章 分离并纠正物理层和数据链路层故障
  8. 我们的年代《音乐天堂》经典回顾
  9. JAVA 蓝桥杯 第十届 省赛 C组 之 [等差数列]
  10. 中学计算机课程课时,高中信息技术课程教学计划
  11. 什么是EJB?不再神秘!
  12. SQL中EXISTS的用法
  13. Java习题练习:1299 String
  14. 使用GitHub Actions实现Hexo博客自动发布
  15. python恶搞代码打开对方摄像头_用Python获取摄像头并实时控制人脸的实现示例
  16. 第二天 05-安装win7系统与远程桌面开启
  17. 机器学习(三)线性回归、广义线性回归、非线性回归
  18. 回归预测分析(RANSAC、多项式回归、残差图、随机森林)
  19. nginx缓冲区关闭导致下载失败问题
  20. 【微软资源站】MSDN

热门文章

  1. docker运行yyets_你应该知道的5个开源Docker工具...
  2. 力创eda 画布大小_立创EDA快速上手经验篇.docx
  3. Improved Techniques for Training GANs
  4. 计算机快捷键桌布,ThinkPad和功能键和快捷键怎么使用
  5. 解决“yyyy-MM-ddTHH:mm:ss+mm:ss” 格式日期转成Date类型
  6. ubuntu16.04 server hbase1.2.6离线安装
  7. 重识三只松鼠:“二次创业”的新变革,“深蹲起跳”的新动能
  8. 如何自动cradle wince模拟器
  9. 近两日,ET消息解读!
  10. 包装实训总结报告_包装设计专业实习报告总结和格式范文