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. 配置Windows Server 2008 允许多用户远程桌面连接

    开启远程桌面后,远程访问windows server 2008服务器时,默认只支持一个用户名同时只能创建一个远程连接,新建连接登录后会将前一个就踢掉,有没有办法像windows server 2005 ...

  2. Win7启动修复MBR(Win7+Linux删除Linux后进入grub rescue的情况)

    事因:我的笔记本原先同时安装了Win7+Linux,昨天发现硬盘实在不够用(才60G,虽然还有个500G的移动硬盘),就想把里面的Ubuntu格了.都是用虚拟机做测试的多.后来就格了Ubuntu所在的 ...

  3. Java实现断点下载Demo

    //1.声明URL String path="http://localhost:8080/day22_DownLoad/file/a.rmvb"; URL url=new URL( ...

  4. String分割类

    StringTokenizer类 用的时候要 import java.util.StringTokenizer; StringTokenizer b=new StringTokenizer( Stri ...

  5. 【回忆1314】抽奖之Flash大转盘

    1.搭建JS与Flash互通的环境 function thisMovie(movieName){ if (window.document[movieName]) { return window.doc ...

  6. Css溢出隐藏

    display: -webkit-box;-webkit-line-clamp: 2;     /*多少行数之后显示为省略...*/word-wrap: break-word;word-break: ...

  7. 在PHP中获取日期和时间

    PHP提供了多种获取时间和日期的函数,除了通过time()函数获取当前的UNIX时间戳外,调用getdate()函数确定当前时间,通过gettimeofday()函数获取某一天中的具体时间.此外,在P ...

  8. Dropbox可伸缩性设计最佳实践分享

    http://www.infoq.com/cn/news/2012/11/dropbox-scale-bestpractice Dropbox的运维工程师Rajiv,跟大家分享了可伸缩性设计的最佳实践 ...

  9. akka简单示例-2

    手动敲了一遍计算pi的示例:http://www.gtan.com/akka_doc/intro/getting-started-first-scala.html 有个笔误,花了半个小时定位. [To ...

  10. HDOJ 1339 A Simple Task(简单数学题,暴力)

    Problem Description Given a positive integer n and the odd integer o and the nonnegative integer p s ...