C++核心技术要点《友元函数,友元类》

本文涉及的产品
实时数仓Hologres,5000CU*H 100GB 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
智能开放搜索 OpenSearch行业算法版,1GB 20LCU 1个月
简介: C++核心技术要点《友元函数,友元类》

1、什么是友元函数?

友元函数就是可以直接访问类的成员(包括私有数据)的非成员函数,也就是说他并不属于这个类,他是一种外部的函数。

一个外部函数只能通过类的授权成为这个类友元函数,这就涉及到一个关键字friend。因为我们的一个外部函数是无法访问一个类的私有数据的,当然可以访问

public修饰的变量,这就不叫私有数据了。

1、友元全局函数

(1)首先说明友元全局函数首先他是一个普通的全局函数,其次他是一个的类的友元函数,也就是意味着我们可以通过友元函数

访问类的私有数据和成员函数,当然首先这个友元函数的参数是一个这个类的引用、类的指针或者就是这个类对象。

(2)声明全局友元函数如下所示:

1 #include <iostream>
 2 using namespace std;
 3 
 4 class Time{
 5     friend void func(Time &t);   // 声明全局函数为一个友元函数
 6 public:
 7     Time(int h, int m, int s) : i_mHour(h), i_mMin(m), i_mSecon(s) { }                  // 构造函数
 8 private:
 9     int i_mHour;
10     int i_mMin;
11     int i_mSecon;
12 };
13 
14 static void func(Time &t)    // 全局函数
15 {
16     cout << t.i_mHour << ":" << t.i_mMin << ":" << t.i_mSecon << endl;
17 }
18 
19 int main(void)
20 {
21     Time t = {10, 20, 30};
22     func(t);
23     return 0;
24 }

全局友元函数

2、友元成员函数

(1)首先说明友元成员函数是一个类的成员函数,其次他是另一个类的友元函数,所以我们也可以在这个函数中访问这个类的私有数据和成员函数

(2)声明友元成员函数如下所示:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Time;
 5 
 6 class Print{
 7 public:
 8     void func(Time &t);   // func函数是Time类的友元函数
 9 };
10 
11 class Time{
12     friend void Print::func(Time &t);  // 声明Print类中的func函数是Time类的友元函数
13 public:
14     Time(int x, int y, int z) : i_mHour(x), i_mMin(y), i_mSecon(z) { }
15 private:
16     int i_mHour;
17     int i_mMin;
18     int i_mSecon;
19 };
20 
21 void Print::func(Time &t)
22 {
23     cout << t.i_mHour << ":" << t.i_mMin << ":" << t.i_mSecon << endl;  // 直接操作Time中的私有数据
24 }
25 
26 int main(void)
27 {
28     Time t(10,20,30);
29     Print p;
30     p.func(t);
31     return 0;
32 }

3、友元类

(1)友元类就是在A类中将B类声明为A类的友元类,方法就是:friend 类名

(2)代码如下:

1 #include <iostream>
 2 using namespace std;
 3 
 4 class Print;
 5 
 6 class Time{
 7     friend Print;         // 声明Print类为Time类的友元类
 8 public:
 9     Time(int x, int y, int z) : i_mHour(x), i_mMin(y), i_mSecon(z) { } // 构造函数
10 private:
11     int i_mHour;
12     int i_mMin;
13     int i_mSecon;
14 };
15 
16 class Print{
17 public:
18     Print(int x, int y, int z) : t(x, y, z) {  }  // 构造函数
19     void func(void);             // 可以在这个函数中去操作Time对象t的私有数据 
20 private:
21     Time t;           // 申明一个Time类对象
22 };
23 
24 void Print::func(void)
25 {
26     cout << t.i_mHour << ":" << t.i_mMin << ":" << t.i_mSecon << endl;  // 直接操作Time中的私有数据
27 }
28 
29 int main(void)
30 {
31     Print p(10,20,30);       // 定义一个Print类对象
32     p.func();                
33     return 0;
34 }

3、注意一些问题

(1)在类中声明的友元函数或者是友元类与类限定符没有任何关系,因为友元函数并不属于这个类,所以类的修饰限定符并不能对他起作用

1 class Time{
 2     friend void func1(Time &t);  // 一般申明在类的开头位置处
 3     ......
 4 public:
 5     friend void func2(Time &t);  // 申明在public下
 6     ......
 7 private: 
 8     friend void func3(Time &t);  // 申明在private下
 9     ......
10 protected:
11     friend void func4(Time &t);  // 申明在protected下
12     ......
13 };

(2)成员函数有this指针,而友元函数没有this指针。

(3)友元函数是不能被继承的,就像父亲的朋友未必是儿子的朋友,这个其实很好理解,也很合理。

(4)友元关系的单向性

A是B的友元,B不是A的友元

(5)友元声明的形式及数量不受限制

我们可以声明多个类的友元函数或者友元类,而且函数可以是一个运算符重载函数,也可以是其他的什么函数。

(6)友元只是封装的补充,其实是破坏了类的封装特性,所以我们如果能够不是用的情况尽量不要去使用。

相关文章
|
3月前
|
存储 算法 C++
C++提高篇:泛型编程和STL技术详解,探讨C++更深层的使用
文章详细探讨了C++中的泛型编程与STL技术,重点讲解了如何使用模板来创建通用的函数和类,以及模板在提高代码复用性和灵活性方面的作用。
64 2
C++提高篇:泛型编程和STL技术详解,探讨C++更深层的使用
|
6月前
|
存储 分布式数据库 API
技术好文:VisualC++查看文件被哪个进程占用
技术好文:VisualC++查看文件被哪个进程占用
|
2月前
|
Java 编译器 C++
c++学习,和友元函数
本文讨论了C++中的友元函数、继承规则、运算符重载以及内存管理的重要性,并提到了指针在C++中的强大功能和使用时需要注意的问题。
29 1
|
4月前
|
人工智能 Anolis
聚焦C++20 最新标准!技术 Workshop 精彩亮点一览 | 2024 龙蜥大会
多场技术 Workshop、多位领域专家亲自授课,分享独家洞察与宝贵经验。
|
4月前
|
算法 C# 开发工具
《黑神话:悟空》背后的编程语言揭秘——超越C++的多元技术融合
【8月更文挑战第27天】在游戏开发领域,一款游戏的成功往往离不开其背后强大的技术支持和编程语言的精妙运用。《黑神话:悟空》作为备受瞩目的国产单机动作游戏,其开发过程不仅涉及了多种编程语言,更是一次技术创新的集中展现。然而,当我们深入探讨其开发语言时,会发现它并非仅依赖于单一的C++,而是融合了多种编程语言的优势,共同铸就了这款游戏的辉煌。
293 0
|
5月前
|
C++
C++友元函数和友元类的使用
C++中的友元(friend)是一种机制,允许类或函数访问其他类的私有成员,以实现数据共享或特殊功能。友元分为两类:类友元和函数友元。类友元允许一个类访问另一个类的私有数据,而函数友元是非成员函数,可以直接访问类的私有成员。虽然提供了便利,但友元破坏了封装性,应谨慎使用。
102 9
|
6月前
|
C++ 索引
C++核心技术要点《运算符重载》
C++核心技术要点《运算符重载》
54 2
|
6月前
|
SQL 人工智能 算法
技术心得记录:模板函数函数模板FunctionTemplate(C++Primer
技术心得记录:模板函数函数模板FunctionTemplate(C++Primer
|
6月前
|
数据采集 自然语言处理 数据挖掘
一文搞懂:【VC++技术杂谈005】如何与程控仪器通过GPIB接口进行通信
一文搞懂:【VC++技术杂谈005】如何与程控仪器通过GPIB接口进行通信
172 0
|
6月前
|
C语言 C++
技术经验分享:c++中的数据类型转换
技术经验分享:c++中的数据类型转换
32 0