1. 为什么要使用友元?

  通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都生命成为 public( 共用的) ,然而这做带来的问题遍是任何外部函数都可以毫无约束的访问它操作它;另一种方法是利用 C++ 的 friend 修饰符,可以让一些你设定的函数能够对这些私有或保护数据进行操作。

2. 使用友元有哪些缺点?

  使用友元的同时也破坏了类的封装特性,这即是友元最大的缺点。当对外声明为友元后,你的所有细节全部都暴露给了对方。

就好像你告诉你朋友你很有钱这个密秘,进而又把你有多少钱,多少古董,多少家产,多少小妾等等所有的家底全给他说了。

3. 友元怎样理解?

  定一个友元函数,或是友元类,就是告诉对方:我的所有元素对你是开放的。这种 friend 是建立在灰常灰常灰常信任对方的基础上的。

4.普通函数做为类的一个友元函数

  在类里声明一个普通函数,在前面加上 friend 修饰,那么这个函数就成了该类的友元。这时这个普通函数可以访问该类的一切成员

#include <iostream >
using namespace std; class MyClass
{
public :
MyClass(string name)
{
m_name = name;
} //声明一个友元函数
friend void Display(MyClass &mycalss); protected:
string m_name;
}; //定义这个友元函数
//写成 void MyClass::Display(MyClass &mycalss)
void Display(MyClass &mycalss)
{
cout << "Access Protected data : "<< mycalss.m_name << endl;
} //测试
int main(int argc,char* argv[])
{
MyClass test("Class A"); Display(test); return ;
}

  说明:

  1. 声明这个友元函数可以在任何地方,可以在 public、protected 当然也可以在 privated 里。

  2. 在这个友元函数里,你可以访问这个类里的所有的成员,所有的成员函数,而不管它是不是 public、protected 或 privated 的。

  3. 定义友元函数时,不能写成 void MyClass::Display(MyClass &mycalss) 这点要注意。因为友元函数不是成员函数

5. 一个普通函数可以是多个类的友元函数

  在每个类里面都有一个友元函数的声明,声明可以有多个,但定义只能有一个

#include <string>
#include <iostream >
using namespace std; class MyClass_B; class MyClass_A
{
public:
MyClass_A(string name)
{
m_name = name;
} //声明一个友元函数
friend void Display(MyClass_A &myA, MyClass_B &myB); private:
string m_name;
}; class MyClass_B
{
public:
MyClass_B(string name)
{
m_name = name;
} //注意,又声明一个友元函数
friend void Display(MyClass_A &myA, MyClass_B &myB); private:
string m_name;
}; //定义这个友元函数
void Display(MyClass_A &myA, MyClass_B &myB)
{
cout << "MyClass A : "<< myA.m_name << endl;
cout << "MyClass B : "<< myB.m_name << endl;
} //测试代码
int main(int argc,char* argv[])
{
MyClass_A testA("Class A");
MyClass_B testB("Class A"); Display(testA, testB);
system("pause");
return ;
}

6.一个类的成员函数也可以是另一个类的友元

//A 类
class MyClass_A
{
public:
MyClass_A(string name)
{
m_name = name;
} void Function(MyClass_B &myB); private:
string m_name;
}; //B 类
class MyClass_B
{
public:
MyClass_B(string name)
{
m_name = name;
} //友元函数声明,注意和普通函数的区别
friend void MyClass_A::Function(MyClass_B &myB); private:
string m_name;
}; //函数定义
void MyClass_A::Function(MyClass_B &myB)
{
cout<<myB.m_name<<endl;
} //测试代码
int main(int argc,char* argv[])
{
MyClass_A testA("Class A");
MyClass_B testB("Class B"); testA.Function(testB);
system("pause");
return ;
}

7. 整个类也可以是另一个类的友元

//类 A
class MyClass_B; class MyClass_A
{
public:
MyClass_A(string name)
{
m_name = name;
} //友元类声明
friend class MyClass_B; private:
string m_name;
}; //类 B
class MyClass_B
{
public:
MyClass_B(string name)
{
m_name = name;
} void Display(MyClass_A &myA); private:
string m_name;
}; //成员函数
void MyClass_B::Display(MyClass_A &myA)
{
cout<<myA.m_name<<endl; //访问A的私有成员 MyClass_A test("test"); cout<<test.m_name<<endl; //好像A的所有元素在B里都存在一样
} //测试代码
int main(int argc,char* argv[])
{
MyClass_A testA("Class A");
MyClass_B testB("Class B"); testB.Display(testA); return ;
}

详解C++ friend关键字的更多相关文章

  1. 转:DesiredCapabilities内容详解--Appium服务关键字

    ## Appium 服务关键字 <expand_table> |关键字|描述|实例| |----|-----------|-------| |`automationName`|你想使用的自 ...

  2. java基础回顾(五)线程详解以及synchronized关键字

    本文将从线程的使用方式.源码.synchronized关键字的使用方式和陷阱以及一些例子展开java线程和synchronized关键字的内容. 一.线程的概念 线程就是程序中单独顺序的流控制.线程本 ...

  3. DesiredCapabilities内容详解--Appium服务关键字

    上次了解了一些DesiredCapabilities的用法,有些还是不太清楚,去appium官网找了找官方文档,觉得写的很全: ## Appium 服务关键字 <expand_table> ...

  4. 【转载】C/C++中extern关键字详解

    1 基本解释:extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义.此外extern也可用来进行链接指定. 也就是说extern ...

  5. JS中this关键字详解

    本文主要解释在JS里面this关键字的指向问题(在浏览器环境下). 阅读此文章,还需要心平气和的阅读完,相信一定会有所收获,我也会不定期的发布,分享一些文章,共同学习 首先,必须搞清楚在JS里面,函数 ...

  6. python关键字详解

    今天依旧在啃:<笨方法学python>,其中习题37是复习各种关键字.我本想百度一下记一下就ok了,但是百度出来第一个就Hongten的博客.我才意识到我也有博客,我应该学习他,把这些积累 ...

  7. JS 中 this 关键字详解

    本文主要解释在JS里面this关键字的指向问题(在浏览器环境下). 首先,必须搞清楚在JS里面,函数的几种调用方式: 普通函数调用 作为方法来调用 作为构造函数来调用 使用apply/call方法来调 ...

  8. ava下static关键字用法详解

    Java下static关键字用法详解 本文章介绍了java下static关键字的用法,大部分内容摘自原作者,在此学习并分享给大家. Static关键字可以修饰什么? 从以下测试可以看出, static ...

  9. 详解js和jquery里的this关键字

    详解js和jquery里的this关键字 js中的this 我们要记住:this永远指向函数运行时所在的对象!而不是函数被创建时所在的对象.this对象是在运行时基于函数的执行环境绑定的,在全局环境中 ...

随机推荐

  1. 嵌套repeater

    通过外层repeater的值来进行内层repeater的数据绑定 前台代码部分: <asp:repeater runat="server" id="repeater ...

  2. python的exec、eval详解

    exec exec语句用来执行储存在字符串或文件中的Python语句.例如,我们可以在运行时生成一个包含Python代码的字符串,然后使用exec语句执行这些语句.下面是一个简单的例子. exec ' ...

  3. DOM基础之“寻找”子节点

    今天学习了JS中的DOM的内容,虽然小菜的理解不深,但希望能够记录下来,慢慢一点一点的进步,有更深的理解了,再回来补充. 首先,关于DOM的概念: 1.概念:DOM = document(文档)Obj ...

  4. 遍历std::list过程中删除元素后继续遍历过程

    std::list::erase Erase elements Removes from the list container either a single element (position) o ...

  5. CSS选择器解析

    通配符选择器 Universal Selector * { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizin ...

  6. CentOS下安装vsftpd架设ftp服务器

    什么是vsftpd vsftpd是一款在Linux发行版中最受推崇的FTP服务器程序.特点是小巧轻快,安全易用. 首先安装vsftpd这个软件,命令是,yum install vsftpd servi ...

  7. office2003万能密钥

    保证有效 OFFICE 2003 :  GWH28-DGCMP-P6RC4-6J4MT-3HFDY

  8. WCF入门教程[WCF基本应用]

    一.概述 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .NE ...

  9. 2017-1-9css

    2017-1-9css css border-image详解 http://www.360doc.com/content/14/1016/13/2792772_417403574.shtml 最简单的 ...

  10. 转:全志A20 GPIO 总结文档

    链接: http://blog.csdn.net/chwenj/article/details/42190745 /* * author:          chwenj@gmail.com. * A ...