首页 > 编程语言 >C++友元函数和友元类的使用

C++友元函数和友元类的使用

时间:2023-08-10 22:31:34浏览次数:41  
标签:友元 函数 私有 void 成员 C++ class 友元类

1.友元介绍

在C++中,友元(friend)是一种机制,允许某个类或函数访问其他类的私有成员。通过友元,可以授予其他类或函数对该类的私有成员的访问权限。友元关系在一些特定的情况下很有用,例如在类之间共享数据或实现特定的功能。

C++友元函数和友元类的使用_直接访问

友元可以分为两种类型:类友元和函数友元。

2.类友元

类友元(Friend Class):

  • 可以将一个类声明为另一个类的友元。这样,在被声明为友元的类中,就可以直接访问另一个类的私有成员。
  • 类友元关系在类之间共享数据或实现特定功能时很有用。
  • 友元关系是单向的,不具有传递性。如果类A是类B的友元,类B不一定是类A的友元。
  • 友元关系通常在类的声明部分使用 friend 关键字来声明。

C++友元函数和友元类的使用_Internet_02

2.1示例代码

class FriendClass {
private:
    int privateData;
public:
    FriendClass() : privateData(0) {}
    friend class OtherClass;  // 声明 OtherClass 是 FriendClass 的友元类
};
class OtherClass {
public:
    void accessPrivateData(FriendClass& obj) {
        obj.privateData = 42;  // 可以直接访问 FriendClass 的私有成员
    }
};

3.函数友元

函数友元(Friend Function)

可以将一个函数声明为一个类的友元函数。这样,在友元函数中可以直接访问该类的私有成员。
友元函数可以是非成员函数,也可以是其他类的成员函数。
友元函数通常在类的声明部分或声明外部使用 friend 关键字来声明。

3.1示例代码

C++友元函数和友元类的使用_Internet_03

class MyClass {
private:
    int privateData;
public:
    MyClass() : privateData(0) {}
    friend void friendFunction(MyClass& obj);  // 声明 friendFunction 是 MyClass 的友元函数
};
void friendFunction(MyClass& obj) {
    obj.privateData = 42;  // 可以直接访问 MyClass 的私有成员
}

4.总结

友元的使用场景包括但不限于以下情况:

  • 当两个或多个类需要共享私有数据时,可以使用类友元来实现数据的直接访问,而无需通过公有接口。
  • 当某个类需要提供特定函数或操作给其他类使用,但这些函数需要访问类的私有成员时,可以使用函数友元。
  • 在重载运算符或实现某些特定功能时,友元可以提供对类私有成员的直接访问。
  • 需要注意的是,友元机制破坏了封装性,因为其他类或函数可以直接访问被授予友元权限的类的私有成员。因此,应谨慎使用友元,只在必要的情况下使用,并且仅将其授予最少的访问权限。

在C++中,我们使用类对数据进行了隐藏和封装,类的数据成员一般都定义为私有成员,成员函数一般都定义为公有的,以此提供类与外界的通讯接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

C++友元函数和友元类的使用_Internet_04

下面我们来看一段代码,看看我们是如何利用友元来访问类的一切成员的:
#include <iostream> 
using namespace std; 
class Internet 
{ 
public: 
Internet(char *name,char *address) // 改为:internet(const char *name , const char *address)
{ 
strcpy(Internet::name,name); 
strcpy(Internet::address,address); 
} 
friend void ShowN(Internet &obj);   //友元函数的声明 
public:              // 改为:private
char name[20]; 
char address[20]; 
}; 
void ShowN(Internet &obj)        //类外普通函数定义,访问a对象的保护成员name,不能写成,void Internet::ShowN(Internet &obj) 
{ 
cout<<obj.name<<endl;          //可访问internet类中的成员
} 
void main() 
{ 
Internet a("谷歌","http://www.google.cn/";); 
ShowN(a); 
cin.get(); 
} 
      示例2:
      分别定义一个类A和类B ,各有一个私有整数成员变量通过构造函数初始化;类A有一个成员函数Show(B &b)用来打印A和B的私有成员变量,请分别通过友元函数和友元类来实现此功能。使用友元类 和 友元函数实现:
#include <iostream>
 
using namespace std;
class B;
class A;
void Show( A& , B& );
 
class B
{
private:
int tt;
friend class A;
friend void Show( A& , B& );
 
public:
B( int temp = 100):tt ( temp ){}
 
};
 
class A
{
private:
int value;
friend void Show( A& , B& );
 
public:
A(int temp = 200 ):value ( temp ){}
 
void Show( B &b )
{
  cout << value << endl;
  cout << b.tt << endl; 
}
};
 
void Show( A& a, B& b )
{
cout << a.value << endl;
cout << b .tt << endl;
}
 
int main()
{
A a;
B b;
a.Show( b );
Show( a, b );
      return 0;
}

C++友元函数和友元类的使用_Internet_05

标签:友元,函数,私有,void,成员,C++,class,友元类
From: https://blog.51cto.com/u_15641375/7040793

相关文章

  • 五子棋_c++版
    #include<bits/stdc++.h>usingnamespacestd;intlie=16,hang=16,lie_shu,hang_shu;intblack_flag[16][16];boolblack=true;intall[16][16];voidf5(){system("cls");for(intj=0;j<=hang;j++){cout<<setw(3)<<......
  • C++/嵌入式八股学习-day3
    目录C++/嵌入式八股学习-day3C/C++使用指针传递大容量参数如何禁止程序自动生成拷贝构造函数?final和override关键字C++类内可以定义引用数据成员吗?auto关键字成员函数里memset(this,0,sizeof(*this))会发生什么ARMSPIz总线的工作频率ARM内部传输数据的总线有哪些?IIC时钟拉伸应用编......
  • 后缀数组C++详解
    后缀定义“后缀i”代表以第i个字符开头的后缀,存储是用i代表字符串s的后缀s[i...n]后缀数组是什么?后缀数组(SuffixArray)主要关系到两个数组:sa和rk。其中,sa[i]表示将所有后缀排序后第i小的后缀的编号,也是所说的后缀数组,后文也称编号数组sa;rk[i]表示后缀i的排名,是重要......
  • 分治算法C++
    1、光荣的梦想题目描述】Prince对他在这片陆上维护的秩序感到满意,于是决定启程离开艾泽拉斯。在他动身之前,Prince决定赋予King_Bette最强大的能量以守护世界、保卫这里的平衡与和谐。在那个时代,平衡是个梦想。因为有很多奇异的物种拥有各种不稳定的能量,平衡瞬间即被打破。KB决定求......
  • 广度优先搜索C++
    1、细胞(1)题目描述一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。如:阵列4100234500067103456050020456006710000000089有4个细胞。【输入】第一行为矩阵的行n和列m;下面为一个n×m......
  • 递归算法练习C++
    1、逆波兰表达式(1)题目描述逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2+3的逆波兰表示法为+23。逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2+3)*4的逆波兰表示法为*+234。本题求解逆波兰表达式的值,其中运算符包括......
  • Google C++ 风格指南记录
    最近在看谷歌的C++风格指南发现了一些有意思的知识点,遂记录下1.第六章第二小节介绍了右值引用只在定义移动构造函数与移动赋值操作时使用右值引用.不要使用 std::forward.定义:右值引用是一种只能绑定到临时对象的引用的一种,其语法与传统的引用语法相似.例如, void......
  • manacher(马拉车)算法C++详解
    马拉车的定义马拉车本质是对中心扩展法(暴力算法)的优化。马拉车是干什么的Manacher算法帮助我们在给定的字符串中找到最长的回文子串。为了简单起见,我们先只处理有奇数个字符的字符串,关于偶数个字符的字符串,在文章最后会给出解法。我们的处理思路和暴力算法基本一致,那就是从左......
  • C/C++基础知识点
    C和C++的区别C++是C的超集,C是面向过程化的结构性语言,而C++是面向对象的编程语言C语言更偏向于底层,使用较为灵活,可移植性强,而C++更偏向于上层,可扩展性强,对于大型项目往往使用C++C++在C语言的基础上提出了STL标准模板库,函数模板等特性static关键字的作用隐藏,凡事变量前添加s......
  • c++枚举详细介绍以及具体用法
    C++中的枚举(Enumeration)是一种用于定义命名常量集合的数据类型。枚举可以提高代码的可读性和可维护性,让您可以使用有意义的名称来表示特定的取值,而不必使用原始的数字常量。枚举的基本语法:enumEnumName{Value1,Value2,//...};EnumName是枚举类型的名称......