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. PL/SQL中文显示都显示成“?”的问题

    PL/SQL中文显示都显示成“?”的问题  首先我在sqlplus里面查询到的中文是正常的,然后再oracle里面的注册表里面看得nls_lang是SIMPLIFIED CHINESE_CHINA.Z ...

  2. Entity Framework 新增实体,新增抽象实体

    抽象实体不能new 抽象类:人,实体类:学生 人 p_人= new 学生();   添加数据,学生和人都添加 抽象类可以提供一个抽象的方法,但是并没有实现,类似接口,但又不同于接口.子类继承父类时必须 ...

  3. php pdo_mysql使用方法

    <?php $dsn='mysql:host=127.0.0.1;port=3306;dbname=bisai'; $username='root'; $password=''; $driver ...

  4. C/C++安全编码-字符串

    1 字符串     1.1 字符串基础 字符串提供命令行参数.环境变量.控制台输入.文本文件及网络连 接,提供外部输入方法来影响程序的行为和输出,这也是程序容易出错的地方.字符串是一个概念,并不是C/ ...

  5. 删除Excel中的打印预览留下的打印线

    Excel 工作表打印后,会留有几条虚线打印线.如下图所示:     不少同学反映,他们尝试了很多操作却仍然无法消除.难道除了重新打开就没有别的办法了? 可以这样做: 在 Excel 2010 中,单 ...

  6. IO通信

    DeviceIoControl 发送控制代码到指定设备驱动程序 参数解释: hDevice Long,设备句柄 dwIoControlCode Long,应用程序调用驱动程序的控制命令,就是IOCTL ...

  7. Mssql显错和不显错模式下的注入

    Title:Mssql显错和不显错模式下的注入 -- 2010-10-27 19:51 近期用手工注入用习惯了,便列出最近用的Mssql语句,以后方便拿来用! -------------------- ...

  8. Java 单例总结

    1:懒汉式,不保证线程安全 package com.yan.singleton; public class LazySingleton { private static final LazySingl ...

  9. Android 之 AlertDialog 用户登录

    1:activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/androi ...

  10. static class

    http://msdn.microsoft.com/zh-cn/library/79b3xss3(VS.80).aspx 不可被继承