C++ 友元
目录
前言
生活中你的家有客厅(Public),有你的卧室(Private)。客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去。但是呢,你也可以允许你的好闺蜜好基友进去。
在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术
友元的目的就是让一个函数或者类 访问另一个类中私有成员
在C++中,友元(friend)是一种特殊的访问机制,它允许类之间的非成员函数或类访问其他类的私有成员。友元提供了一种在不侵犯封装性的情况下,使外部函数或类能够与类内部进行交互的方式。
在C++中,友元有三种类型:
- 全局函数做友元
- 类做友元
- 成员函数做友元
全局函数做友元
友元函数(友元非成员函数):友元函数是在类外部定义的非成员函数,在类声明中使用
friend
关键字进行声明。友元函数可以访问该类的私有成员和受保护成员
简单例
class MyClass {
private:
int privateVar;
public:
friend void friendFunc(MyClass obj); // 友元函数的声明
};
void friendFunc(MyClass obj) {
obj.privateVar = 10; // 可以访问私有成员
}
详细例?
#include <iostream>
#include <string>
using namespace std;
/*
友元的三种实现
* 全局函数做友元
* 类做友元
* 成员函数做友元
*/
class Building
{
// 全局函数做友元: goodGay全局函数加关键字 friend 是Building类的好朋友,可以访问类中的私有内容
friend void goodGay(Building * building);
public:
Building()
{
m_SittingRoom = "客厅"; // 默认 this->m_SittingRoom,下面同理
m_BedRoom = "卧室";
}
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom; //卧室
};
void goodGay(Building * building)
{
cout << "好基友正在访问: " << building->m_SittingRoom << endl; // 客厅
cout << "好基友正在访问: " << building->m_BedRoom << endl; // 卧室(private私有成员也可以访问了)
}
void test01()
{
class Building building;
goodGay(&building);
}
int main() {
test01();
return 0;
}
?类做友元
友元类(友元类成员函数):友元类允许其他类的成员函数访问该类的私有成员和受保护成员。在类声明中使用
friend
关键字声明其他类作为友元类。
简单例
class MyClass {
private:
int privateVar;
public:
friend class FriendClass; // 友元类的声明
};
class FriendClass {
public:
void accessPrivateVar(MyClass obj) {
obj.privateVar = 10; // 可以访问私有成员
}
};
详细例?
#include <iostream>
using namespace std;
#include <string>
class Building;
class goodGay
{
public:
goodGay();
void visit();
private:
Building *building; // buiilding类对象地址
};
class Building
{
//告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容
friend class goodGay;
public:
Building(); // 构造函数
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom;//卧室
};
Building::Building() // init 类Building的构造函数
{
this->m_SittingRoom = "客厅";
this->m_BedRoom = "卧室";
}
goodGay::goodGay() // init 类goodGay的构造函数
{
/*
new: new Building可以使用new运算符创建类对象,并在分配内存时调用类的构造函数。并返回指向该内存块起始位置的指针
new: new int(10) 可以动态开辟一个int类型的内存块。存放数据10,并返回这个地址
*/
this->building = new Building;
}
void goodGay::visit()
{
cout << "好基友正在访问" << this->building->m_SittingRoom << endl; // 客厅
cout << "好基友正在访问" << this->building->m_BedRoom << endl; // 卧室 (私有成员)
}
void test01()
{
goodGay gg;
gg.visit();
}
int main() {
test01();
return 0;
}
成员函数做友元
友元成员函数(友元类成员函数):友元成员函数是一个类的成员函数,它可以访问另一个类的私有成员和受保护成员。在类声明中使用
friend
关键字将另一个类的成员函数声明为友元成员函数。
简单例
class MyClass {
private:
int privateVar;
public:
friend void FriendClass::accessPrivateVar(MyClass obj); // 友元成员函数的声明
};
class FriendClass {
public:
void accessPrivateVar(MyClass obj) {
obj.privateVar = 10; // 可以访问私有成员
}
};
详细例?
#include <iostream>
using namespace std;
#include <string>
class Building;
class GoodGay
{
public:
GoodGay(); // 构造函数
void visit(); // 只让visit函数作为Building的好朋友,可以访问Building中私有内容
void visit2();
private:
Building *building;
};
class Building
{
// 告诉编译器 goodGay类中的visit成员函数 是Building好朋友,可以访问私有内容
friend void GoodGay::visit();
public:
Building(); // 构造函数
public:
string m_SittingRoom; //客厅
private:
string m_BedRoom;//卧室
};
Building::Building()
{
this->m_SittingRoom = "客厅";
this->m_BedRoom = "卧室";
}
GoodGay::GoodGay() // 初始构造函数
{
this->building = new Building; // 创建一个Building类实例,返回这个实例的地址,用于管理这个类实例
}
void GoodGay::visit()
{
cout << "好基友正在访问" << this->building->m_SittingRoom << endl; // 客厅
cout << "好基友正在访问" << this->building->m_BedRoom << endl; // 卧室
}
void GoodGay::visit2()
{
cout << "好基友正在访问" << this->building->m_SittingRoom << endl; // 客厅
//cout << "好基友正在访问" << building->m_BedRoom << endl; err
}
void test01()
{
class GoodGay gg;
gg.visit();
}
int main() {
test01();
return 0;
}
友元在C++中的应用场景?
-
访问私有成员:友元可以让一个非成员函数或类的成员函数访问另一个类的私有成员和受保护成员。这在某些特定情况下是有用的,比如需要在类外部定义的函数中操作类的私有成员数据。
-
操作符重载:友元可以在操作符重载中使用,以便访问类的私有成员或进行特定的操作。例如,重载输出流操作符
<<
时,可以将输出流函数声明为友元函数,以便直接访问类的私有成员并输出它们。 -
类之间的交互:有时不同的类之间需要进行密切的交互,以便共享私有成员或实现某些特定功能。此时可以使用友元类来实现类之间的交互,确保类可以直接访问对方的私有成员。
-
跨越继承层次结构:在继承关系中,子类通常无法直接访问父类的私有成员。但是,通过添加友元关系,可以使父类中的成员函数能够访问子类的私有成员,从而实现更灵活的设计。
注意点
友元关系是单向的。如果类A是类B的友元类,不意味着类B也是类A的友元类。同时,友元关系不继承。子类不自动拥有其父类的友元。
友元的使用应慎重,因为它可能破坏类的封装性。仅在必要的情况下使用友元,以确保良好的设计和封装。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!