文章参考:【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),即已前向声明的类是一个类型,但所包含的成员未知,仅能以有限方式使用。
不完全类型可定义该类的指针、引用,以及声明(并非定义)将该类作为形参类型或返回类型的函数;但不能定义该类对象。