《C++避坑神器·五》友元函数(friend)使用看这篇就够

简介: 《C++避坑神器·五》友元函数(friend)使用看这篇就够


概要

友元函数(friend)使用,访问类中的私有变量

技术细节

目的:让一个函数或者类访问另一个类中私有成员

友元三种实现:

(1)全局函数做友元

(2)类做友元

(3)成员函数做友元

全局函数做友元:

class Room
{
  //把全局函数声明在类中加friend修饰可以访问类中私有变量
  friend void FriendFun(Room* room);
public:
  Room()
  {
    sittingRoom = "客厅";
    bedRoom = "卧室";
  }
  string sittingRoom;
private:
  string bedRoom;
};
//全局函数
void FriendFun(Room * room)
{
  std::cout << room->bedRoom << std::endl;
}
int main()
{
  Room room;
  FriendFun(&room);
}

类做友元:

class Room
{
  //把友元类加friend修饰可以访问类中私有变量
  friend class FriendClass;
public:
  Room()
  {
    sittingRoom = "客厅";
    bedRoom = "卧室";
  }
  string sittingRoom;
private:
  string bedRoom;
};
//友元类
class FriendClass
{
public:
  FriendClass();
  void FriendFun();
  Room* room;
};
FriendClass::FriendClass()
{
  room = new Room();
}
void FriendClass::FriendFun()
{
  std::cout << room->bedRoom << std::endl;
}
int main()
{
  FriendClass fc;
  fc.FriendFun();
}

成员函数做友元(易错!):

class Room;
//友元类
class FriendClass
{
public:
  void FriendFun(Room& room);
};
class Room
{
  //把友元类加friend修饰可以访问类中私有变量
  friend void FriendClass::FriendFun(Room& room);
public:
  Room()
  {
    sittingRoom = "客厅";
    bedRoom = "卧室";
  }
  string sittingRoom;
private:
  string bedRoom;
};
void FriendClass::FriendFun(Room& room)
{
  std::cout << room.bedRoom << std::endl;
}
int main()
{
  Room room;
  FriendClass fc;
  fc.FriendFun(room);
}

FriendClass类成员函数想访问Room类中的私有成员

如果一开始把Room类的定义放在最前面而不是声明,这样会报错,因为Room类中引入了友元函数FriendFun,而FriendFun函数是在FriendClass类中定义的,在定义Room类的时候FriendFun函数还没有出现,所有会报错,这就需要把FriendClass类定义在最前面。

又由于FriendClass类的FriendFun函数引入了需要传入Room类的引用,所以必须在FriendClass类前声明Room类告诉FriendFun函数传入的Room类的引用是存在的。FriendFun函数要写在Room类之后,因为函数内部用到了bedroom变量,这是Room类中的变量,所以Room类要先定义。(如果bedRoom打红杠是因为编译器没有识别出来,但不影响编译,可以编译通过,不用理会)

如果先声明FriendClass类,在定义Room类对不对呢?

这样不对,先声明FriendClass类,说明可以在Room类中传入FriendClass类引用了,但Room类中有友元函数FriendFun,目前我只知道FriendClass类声明了,有这个类,但我不知道类中会不会有FriendFun函数,所以Room类中有友元函数FriendFun是不对的,所以不能先声明FriendClass类在定义Room类。

易错写法:!!!

class Room;
//友元类
class FriendClass
{
public:
  void FriendFun();
  Room room;
};
class Room
{
  //把友元类加friend修饰可以访问类中私有变量
  friend void FriendClass::FriendFun();
public:
  Room()
  {
    sittingRoom = "客厅";
    bedRoom = "卧室";
  }
  string sittingRoom;
private:
  string bedRoom;
};
void FriendClass::FriendFun()
{
  std::cout << room.bedRoom << std::endl;
}
int main()
{
  Room room;
  FriendClass fc;
  fc.FriendFun();
}

报错:严重性 代码 说明 项目 文件 行 禁止显示状态

错误 C2079 “FriendClass::room”使用未定义的 class“Room”

这样写按道理没有错,为啥还报room使用未定义的类Room?

class Room;是一个前向声明,在类的声明之后,定义之前,此类是一个不完全类型,即已知前向声明过的类是一个类型,但不知道包含哪些成员。不完全类型只能以有限方式使用,不能定义该类型对象,不完全类型只能用于定义指向该类型的指针或者引用,或者用于声明(而不是定义)使用该类型作为形参类型或者返回类型的函数。

这样的话怎么修改?

把Room room改为指针类型Room *room; 同时要在FriendClass 类中写一个无参构造,里面给room分配动态内存,room=new Room; 不然room是野指针。

第二种修改就是声明带该类型作为形参的函数void FriendFun(Room &room);或void FriendFun(Room room);

相关文章
|
2月前
|
Java 编译器 C++
c++学习,和友元函数
本文讨论了C++中的友元函数、继承规则、运算符重载以及内存管理的重要性,并提到了指针在C++中的强大功能和使用时需要注意的问题。
29 1
|
3月前
|
编译器 数据安全/隐私保护 C++
C++(十四) friend友元
友元机制允许非成员函数或类访问私有成员,提高程序效率,但会破坏封装性。友元可以是函数或类,并以关键字`friend`声明。友元函数不是成员函数,需通过对象访问私有成员。友元类使所有成员函数可访问另一个类的私有成员,常用于简化开发。友元声明位置灵活,但不影响访问控制。使用友元需注意其单向性和非传递性。
|
5月前
|
C++
C++友元函数和友元类的使用
C++中的友元(friend)是一种机制,允许类或函数访问其他类的私有成员,以实现数据共享或特殊功能。友元分为两类:类友元和函数友元。类友元允许一个类访问另一个类的私有数据,而函数友元是非成员函数,可以直接访问类的私有成员。虽然提供了便利,但友元破坏了封装性,应谨慎使用。
102 9
|
6月前
|
C++
C++核心技术要点《友元函数,友元类》
C++核心技术要点《友元函数,友元类》
62 3
|
7月前
|
算法 C++
C++中的友元类(Friend Classes)技术详解
C++中的友元类(Friend Classes)技术详解
324 0
|
7月前
|
设计模式 缓存 编译器
【C++友元函数】深入探索C++友元函数:从基础到应用
【C++友元函数】深入探索C++友元函数:从基础到应用
143 0
|
7月前
|
Serverless C++
[C++/PTA] 计算点到直线的距离一一友元函数的应用
[C++/PTA] 计算点到直线的距离一一友元函数的应用
165 0
|
7月前
|
C++
[C++/PTA] 2017final友元函数之全班同学的平均绩点
[C++/PTA] 2017final友元函数之全班同学的平均绩点
154 0
《C++避坑神器·二十三》C++异常处理exception
《C++避坑神器·二十三》C++异常处理exception
80 0