C++之友元函数

article/2025/9/17 11:56:25

目录

1.定义:

1.概念:

2.注意

3.友元的分类:

4.友元函数代码分析:

1.友元函数出现的原因(外部函数友元为例):

2.一个外部函数作为多个类的友元函数

3.成员函数友元:

4.类友元:

5.特点:

1.不具有对称性 :

2.不具有传递性 :

3.不具有继承性:

6.总结:

1.友元函数不是类的成员函数。

2.友元函数不受类中的访问权限关键字限制。

3.某类的友元函数的作用域并非该类作用域。


1.定义:

1.概念:

友元 friend 机制允许一个类授权其他的函数访问它的非公有成员。友元声明以关键字 friend 开头 ,它只能出现在类的声明中, 它们不受其在类体中的 public private 和 protected 区的影响.。

通俗来说就是就是让函数或者类作为另外一个类的朋友,则可以访问当前类的private或者protected类。

2.注意

1.一个普通函数作为类的友元,那么在当前函数中就可以通过对象访问类的私有或者保护成员
  注意:这个函数只能在外部定义,在当前类中引用即可
2.一个类的成员函数作为另外一个类的友元
  注意:成员函数建议放在类外定义
3.一个类A作为另外一个类B的友元类,则A的所有的成员函数就可以访问B的私有数据成员或者保护

3.友元的分类:

友元分为外部函数友元, 成员函数友元,类友元。

4.友元函数代码分析:

1.友元函数出现的原因(外部函数友元为例):

class A
{
public:A(int i=0):m_i(i){}
private:int m_i;
};void main()
{A a(5);A b(8);Add(a, b);
}
想在Add函数中访问私有数据成员,在之前我们通过接口实现了Add函数,那如果不想通过接口(共有函数),我们可以怎么实现呢?
class A
{
public:A(int i=0):m_i(i){}int GetI()const{return m_i;}friend void Add(A& a, A& b);//将Add函数作为类A的友元,在类外部定义,(不能在类A中定义)
protected://friend void Add(A& a, A& b);
private:int m_i;//friend void Add(A& a, A& b);
};//想在Add函数中访问私有数据成员,又不想通过接口(公有函数)
void Add(A& a, A& b)
{cout << a.m_i + b.m_i << endl;//cout << a.GetI() + b.GetI() << endl;//接口
}
void main()
{A a(5);A b(8);Add(a, b);
}

402be56990684a89a4283e6656db125f.png

分析:

1.在类A的外部写入了一个公有函数

2.在类A中写入friend void Add(A& a, A& b);即就是将Add函数作为类A的友元,

注意该函数只能在类A的外部定义

3.即A可以访问Add函数,对a,b进行求和。

该例子为外部函数友元

2.一个外部函数作为多个类的友元函数

那如果一个外部函数作为多个类的友元函数,代码是完全一样的吗?

不完全一样,需要前向引用声明。

class B;//前向引用声明
class C;
class A
{
public:A(int i = 0) :m_i(i) {}friend int Sum(A& a, B& b, C& c);
private:int m_i;
};
class B
{
public:B(int j = 0) :m_j(j) {}friend int Sum(A& a, B& b,C& c);
private:int m_j;
};
class C
{
public:C(int k = 0) :m_k(k) {}friend int Sum(A& a, B& b,C&c);
private:int m_k;
};
int Sum(A& a, B& b,C&c)
{return a.m_i + b.m_j+c.m_k;
}
void main()
{A a(10);B b(20);C c(30);cout << Sum(a, b, c) << endl;
}

0a9c441b79144cc7bdc1861840b0c5cc.png

分析:

1.在类A、B、C的外部写入了一个公有函数Sum

2.在类A、B、C中均写入friend void Add(A& a, A& b);即就是将Add函数作为类A的友元,

顺序不是第一个的类必须向前引用声明, 否则会出现以下错误:

47d3a5038f414627834fafc0f3abdc29.png

3.成员函数友元:

有若干不同的类,究竟哪个应该放在首个,哪些向前引用声明呢?

class C;
class A;
class B
{
public:B(int j = 0) :m_j(j) {}void Sub(A& a, B& b, C& c);void Print(A& a);
private:int m_j;
};
class A
{
public:A(int i = 0) :m_i(i) {}friend void B::Sub(A& a, B& b, C& c);friend void B::Print(A&a);
private:int m_i;
};
class C
{
public:C(int k = 0) :m_k(k) {}friend void B::Sub(A& a, B& b, C& c);
private:int m_k;
};
void B::Sub(A& a,B&b,C&c)
{cout << a.m_i - m_j +c.m_k<< endl;
}
void B::Print(A&a)
{cout << a.m_i << endl;
}
void main()
{A a(10);B b(20);C c(30);b.Sub(a,b,c);b.Print(a);
}
分析: 一般情况下,把声明函数的类放在前面,函数的定义写在类的外面 aee82934688b4ba29031b2d5ec5f566a.png

class A
{
public:A(int i = 0) :m_i(i) {}friend void B::Sub(A& a, B& b, C& c);friend void B::Print(A&a);
private:int m_i;
}

在这段代码中类B的成员函数Sub、Print都作为了类A的友元

4.类友元:

class B;
class A
{
public:A(int a = 0) :m_a(a) {}void print(B& b);void test(B& b);void show(B& b);
private:int m_a;
};
class B
{
public:B(int b=0):m_b(b){}friend class A;
private:int m_b;
};void A::print(B& b)
{cout << "a::print:" << b.m_b << endl;
}
void A::test(B& b)
{cout << "a::test:" << b.m_b << endl;
}
void A::show(B& b)
{cout << "a::show:" << b.m_b << endl;
}
void main()
{A a(2);B b(10);a.print(b);a.show(b);a.test(b);
}

类A作为类B的友元函数,(在B中写friend class A的意思就是:告诉B,A是它的friend),所以类A可以访问类B中的所有函数,只需在类A中声明。

e28d7a00809e4fafb832f4f2f6ece81c.png

A、B两类也可以互为友元类

class B;
class A
{
public:A(int a = 0) :m_a(a) {}void print(B& b);void test(B& b);void show(B& b);friend class B;
private:int m_a;
};
class B
{
public:B(int b=0):m_b(b){}friend class A;void Print(A& a);
private:int m_b;
};
void B::Print(A& a)
{cout << a.m_a << endl;
}
void A::print(B& b)
{cout << "a::print:" << b.m_b << endl;
}
void A::test(B& b)
{cout << "a::test:" << b.m_b << endl;
}
void A::show(B& b)
{cout << "a::show:" << b.m_b << endl;
}
void main()
{A a(2);B b(10);a.print(b);a.show(b);a.test(b);b.Print(a);
}

6ce5b4787abb49639abe7e2f9c433002.png

A、B互为友元类,即就是,只要声明了,就可以访问友元类的成员函数。 

5.特点:

1.不具有对称性 :

A 是 B 的友元, 并不意味着 B 是A的友元。

class B;
class A
{
public:A(int a = 0) :m_a(a) {}void print(B& b);void test(B& b);void show(B& b);
private:int m_a;
};
class B
{
public:B(int b=0):m_b(b){}friend class A;void Print(A& a);
private:int m_b;
};
void B::Print(A& a)
{cout << a.m_a << endl;
}
void A::print(B& b)
{cout << "a::print:" << b.m_b << endl;
}
void A::test(B& b)
{cout << "a::test:" << b.m_b << endl;
}
void A::show(B& b)
{cout << "a::show:" << b.m_b << endl;
}
void main()
{A a(2);B b(10);a.print(b);a.show(b);a.test(b);b.Print(a);
}

fc08dde90f1647bf968af44c880f209f.png

 没有告诉A:B是它的朋友,所以B不能访问A 的私有成员

2.不具有传递性 :

A是B的友元, B是C的友元, 但A不是C的友元。

class AA
{
public:friend class BB;
private:int m_a;
};
class BB
{
public:friend class CC;void Show(AA& a);
private:int m_b;
};
class CC
{
public:void printf(BB& b);void test(AA& a);
};
void BB::Show(AA& a)
{cout << a.m_a << endl;
}
void CC::printf(BB& b)
{cout << b.m_b << endl;
}
void CC::test(AA& a)//友元是不能进行传递的
{//cout << a.m_a << endl;//error
}
void main()
{AA a;BB b;CC c;b.Show(a);c.printf(b);c.test(a);//error
}
void CC::test(AA& a)//友元是不能进行传递的
{
    //cout << a.m_a << endl;//error
}
* BB是AA 的朋友
* CC是BB 的朋友
//CC不是AA的朋友,不能访问AA的数据成员 8f2e75d0531d44248e0e2314abf8e096.png

3.不具有继承性:

Base 类型继承 Object类型, 如果Object 类型是A的友元,但Base类型不是A友 元。

6.总结:

1.友元函数不是类的成员函数。

在函数体中访问对象的成员,必须用对象名加运算符“.”加对象成员 名。但友元函数可以访问类中的所有成员,一般函数只能访问类中的公有成员。

2.友元函数不受类中的访问权限关键字限制。

可以把它放在类的公有、私有、保护部分,但结果一 样。

3.某类的友元函数的作用域并非该类作用域。

如果该友元函数是另一类的成员函数,则其作用域为 另一类的作用域,否则与一般函数相同。


http://chatgpt.dhexx.cn/article/Au9vYdN0.shtml

相关文章

友元 基础详解版 (友元函数、友元类、友元非成员函数和友元成员函数)

友元 一般来说&#xff0c;类的公有成员能够在类外访问&#xff0c;私有的成员只能被类的其他成员函数访问。 在C中&#xff0c;可以定义友元&#xff0c;如果某一个函数定义为类的友元&#xff0c;则该函数就可以访问该类的私有函数。也可以把一个类定义为另一个类的友元。 …

win7快捷方式去箭头_win7旗舰版桌面图标快捷方式箭头变成黑块怎么办?

大家在使用win7的过程中&#xff0c;发现桌面图标快捷方式箭头变成黑块&#xff0c;这时我们应该怎么解决呢&#xff0c;请继续往下看&#xff01; 操作过程&#xff1a; 1、在winr调出运行窗口&#xff0c;键入regedit.exe&#xff0c;回车&#xff0c;打开注册表编辑器。 依次…

去掉桌面快捷方式箭头和快捷方式字样--美化桌面快捷方式

去掉桌面快捷方式箭头和快捷方式字样--美化桌面快捷方式&#xff0c;如图&#xff1a; 下载地址&#xff1a; https://download.csdn.net/download/lhyhr/12700649

恢复Windows7快捷方式小箭头的方法

电脑重新安装了一个Windows7的纯净版系统&#xff0c;结果快捷方式的小箭头不见了。在网上查到的各种修改注册表的方式都试过之后&#xff0c;依然无效。 后来看到有人介绍可以使用软件恢复&#xff0c;于是下载了一个软件&#xff1a;Windows快捷方式小箭头管理&#xff0c;结…

Windows系统桌面快捷方式图标去除小箭头

在注册表”HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons“项下新建字符串值&#xff0c;命名为29&#xff0c;数据为&#xff1a;”%systemroot%\system32\imageres.dll,197“。 注销重新登录后小箭头即不显示&#xff0c;反之则删除名…

win8电脑怎么把计算机快捷方式,Win8怎么隐藏桌面快捷方式小箭头_Win8去掉快捷方式箭头-192路由网...

本文主要介绍了Win8电脑上&#xff0c;去掉桌面快捷方式小箭头的方法。Win8电脑桌面上的快捷方式&#xff0c;默认是有一个小箭头的&#xff0c;看起来非常不美观。 因此&#xff0c;很多用户想把Win8快捷方式上的小箭头去掉&#xff0c;却又不知道应该如何设置。 其实去掉Win8…

去除win10桌面图标快捷方式小箭头

同样用命令行来解决&#xff0c;管理员打开CMD&#xff0c;输入下面代码 &#xff08;也可以做成bat批处理文件&#xff0c;管理员运行&#xff09; 移除小箭头&#xff1a; reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Ic…

Win11清除桌面快捷方式小箭头

Win11清除桌面快捷方式小箭头 1.WinR输入regedit&#xff0c;进入注册表。 2.找到路径\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons 选择右边名称为29的项&#xff08;部分电脑系统没有Shell Icons这个选项&#xff0c;那么在上一级…

玩机技巧|去除Windows桌面快捷方式图标左下角上的小箭头

当我们下载了软件之后在桌面上左下角都会有一个快捷方式的小箭头&#xff0c;如何去掉这个小箭头让桌面图标变得更加清爽一些呢。现在教大家一个简单的办法。 修改注册表 编辑代码 管理员身份运行 选择去除小箭头 检测 恢复小箭头 修改注册表 去除这个小箭头的方法很简单&…

win10去掉快捷方式小箭头(win10桌面快捷方式小箭头怎么去掉)

桌面快捷方式小箭头怎么去掉 在我的电脑处右击——属性——高级——性能中的设置——视觉效果中选择调整为最佳外观&#xff0c;确定后即可。或者选择自定义&#xff0c;然后在窗口里把“在桌面上为图标标签使用阴影”这条前面的勾去掉就行了。 WIN10怎么去掉快捷方式小箭头&am…

如何恢复快捷方式上的小箭头

接上一篇博客&#xff0c;我们应该怎么把已经去掉的小箭头恢复。 第一步&#xff0c;新建一个txt文本文档&#xff0c;输入中括号内的内容&#xff1a; 【 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\PIPFile] “IsShortcut”"" [HKEY_CLASSES_ROOT\…

win11删除快捷方式的小箭头.bat

步骤 新建一个txt文件&#xff0c;改名为xxx.bat右键&#xff0c;编辑&#xff0c;修改内容为&#xff1a; reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons" /v 29 /d "%systemroot%\system32\imageres.dll,197…

去除Ubuntu 20桌面图标的快捷方式箭头

去除Ubuntu 20桌面图标的快捷方式箭头 当创建快捷方式到桌面时&#xff0c;图标上会显示一个快捷方式箭头&#xff0c; 真的很难看&#xff0c;想要隐藏&#xff0c;但又无法找到设置的地方在哪里&#xff0c; 于是我想到一个简单粗暴的方法&#xff0c;直接将这个图片替换成…

Win10 去除桌面快捷方式箭头

Win10去除桌面快捷方式小箭头 新建文本文档&#xff0c;将下面的代码复制进去&#xff0c;保存。重命名文件&#xff0c;改为 文件名.bat&#xff0c;保存。(注意这里的后缀必须是bat格式。) 然后右键&#xff0c;以管理员身份运行该文档&#xff0c;即可去除小箭头。 reg …

linux去除快捷方式箭头,焦点去除Win8快捷方式箭头软件

焦点去除Win8快捷方式箭头软件是焦点工作室为Win8用户打造的去除箭头专属软件&#xff1b;软件界面依旧延续了界面简洁、通俗明了、便捷实用的经典特色。。 相关软件软件大小版本说明下载地址 焦点去除Win8快捷方式箭头软件是焦点工作室为Win8用户打造的去除箭头专属软件&#…

解决win10去掉桌面快捷方式箭头的方法

大家安装完一个软件后&#xff0c;都会在桌面上自动生成一个快捷方式&#xff0c;还会在左下角出现一个小箭头&#xff0c;很多用户觉得看起来不美观&#xff0c;那有什么办法可以去掉快捷方式上面的小箭头吗&#xff1f; 操作过程&#xff1a; 1、按下键盘上的“WinR”直接打开…

好用的网页在线客服工具

在线实时聊天是线上店铺吸引并留住客户的有力工具&#xff0c;在线聊天能够提高潜在客户的服务体验&#xff0c;而好用的网页在线客服工具可以成为客服人员的好帮手。 前言 线下门店有专职的销售人员在场&#xff0c;客户遇到问题随时可以进行咨询&#xff0c;极有可能直接促成…

2022淘宝中秋营销攻略,请查收!

又一年中秋快到了&#xff0c;开淘宝店的同行小伙伴们打算上啥促销活动呀&#xff1f;以怎样的形式开展呢&#xff1f;这篇中秋营销攻略来得很及时啦&#xff01;你一定要看哦&#xff01; 一、活动策划&#xff08;运营须知&#xff09; 中秋大家可能第一时间想到就是月饼啊&…

简单几招教您玩转客服营销,提高宝贝转化率!

其实&#xff0c;做淘宝的卖家都明白&#xff0c;宝贝卖不出去很多都是因为没有及时的催付&#xff0c;因此导致流失了很多订单。从顾客的行为合理分析来看&#xff0c;恰当时机进行催付&#xff0c;不仅可以提高店铺销售额&#xff0c;降低推广成本&#xff0c;同时可以达到事…

【客服准则】浅谈服务差异化对转化的重要性

大家发现吗&#xff1f;售卖相同类目的店铺&#xff0c;除去产品质量、付费推广等因素&#xff0c;客户服务的差异化直接影响着店铺的成交转化率。 据中商情报网《2017.12~2021.12网络购物用户规模及使用情况》显示&#xff1a;“80-90 后”网购普及最高&#xff0c;“95 后”消…