概要
友元函数(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);
本文详细介绍了如何通过全局函数、友元类和成员函数三种方式让函数或类访问另一个类的私有变量。特别强调了友元函数的使用规则,包括易错点和修正方法。
5467

被折叠的 条评论
为什么被折叠?



