C++类和对象(四):友元(全局函数、类、成员函数作友元)

文章参考:【C++】错误C2027:使用了未定义类型错误原因


0 友元

作用:在类中使用关键字friend修饰类外某些函数声明,使其可访问类中的私有成员

友元的3种实现
(1)全局函数作友元
friend 全局函数声明;friend 返回类型 友元全局函数名(类引用或类指针);
(2)作友元
friend 类声明;friend class 友元类名;
(3)成员函数作友元
friend 友元成员函数所属类名::成员函数声明;friend 返回类型 友元成员函数所属类名::友元成员函数名(形参列表);


1 全局函数作友元

用法friend 全局函数声明;friend 返回类型 友元全局函数名(类引用或类指针);

#include <iostream>
using namespace std;
#include <string>

class House {
    
    
	/* 全局函数作友元 */
	friend void g_canVisit(House *pHouse);

private:
	string bedroom;

public:
	string livingroom;

	House();	//类内声明构造函数
};

//类外定义构造函数
House::House() {
    
    
	livingroom = "客厅";
	bedroom = "卧室";
}

/* 全局函数 */
void g_canVisit(House *pHouse) {
    
    
	cout << "正在访问:" << pHouse->livingroom << endl;

	//未对全局函数设置友元时,无法访问私有成员
	cout << "正在访问:" << pHouse->bedroom << endl;
}

int main() {
    
    
	House* house = new House;	//在堆区创建对象
	g_canVisit(house);			//正在访问:客厅;正在访问:卧室

	return 0;
}

2 类作友元

用法friend 类声明;friend class 友元类名;

#include <iostream>
using namespace std;
#include <string>

/* 类的前向声明 */
//Family类中未知House类的成员,仅能定义House类的指针、引用,以及House类作为形参或返回类型的函数声明
class House;

//友元类
class Family {
    
    
private:
	House* pHouse;

public:
	Family();

	void canVisit();
};

class House {
    
    
	/* 类作友元 */
	friend class Family;

private:
	string bedroom;		//私有成员

public:
	string livingroom;	//公共成员

	House() {
    
    
		livingroom = "客厅";
		bedroom = "卧室";
	}
};

/* 为避免使用类的前向声明时误用该类成员报错,在类外定义成员函数 */
Family::Family() {
    
    
	pHouse = new House;
}

void Family::canVisit() {
    
    
	cout << "正在访问:" << pHouse->livingroom << endl;	//使用前向声明类的成员

	//未对类设置友元时,无法访问私有成员
	cout << "正在访问:" << pHouse->bedroom << endl;	//使用前向声明类的成员
}


int main() {
    
    
	Family family;
	family.canVisit();	//正在访问:客厅;正在访问:卧室

	return 0;
}

3 成员函数作友元

用法friend 友元成员函数所属类名::成员函数声明;friend 返回类型 友元成员函数所属类名::友元成员函数名(形参列表);

#include <iostream>
using namespace std;
#include <string>

/* 类的前向声明 */
//Family类中未知House类的成员,仅能定义House类的指针、引用,以及House类作为形参或返回类型的函数声明
class House;

//友元类
class Family {
    
    
private:
	House *pHouse;

public:
	Family();

	/* 对成员函数设置友元 */
	void canVisit();

	/* 未对成员函数设置友元 */
	void canNotVisit();
};


class House {
    
    
	/* 成员函数作友元 */
	friend void Family::canVisit();

private:
	string bedroom;		//私有成员

public:
	string livingroom;	//公共成员

	House() {
    
    
		this->livingroom = "客厅";
		this->bedroom = "卧室";
	}
};

/* 为避免使用类的前向声明时误用该类成员报错,在类外定义成员函数 */
Family::Family() {
    
    
	pHouse = new House;
}

//对成员函数设置友元
void Family::canVisit() {
    
    
	cout << "正在访问:" << pHouse->livingroom << endl;	//使用前向声明类的成员

	//对成员函数设置友元时,可访问私有成员
	cout << "正在访问:" << pHouse->bedroom << endl;	//使用前向声明类的成员
}

//未对成员函数设置友元
void Family::canNotVisit() {
    
    
	cout << "正在访问:" << pHouse->livingroom << endl;	//使用前向声明类的成员

	//未对成员函数设置友元时,无法访问私有成员
	//cout << "正在访问:" << pHouse->bedroom << endl;
}


int main() {
    
    
	Family family;
	family.canVisit();		//正在访问:客厅;正在访问:卧室
	family.canNotVisit();	//正在访问:客厅

	return 0;
}

类的前向声明
类在声明后、定义前,属于不完全类型(incompete type),即已前向声明的类是一个类型,但所包含的成员未知,仅能以有限方式使用。
不完全类型可定义该类的指针引用,以及声明(并非定义)将该类作为形参类型或返回类型的函数;但不能定义该类对象

猜你喜欢

转载自blog.csdn.net/newson92/article/details/113661732