报错代码
在学友元时,自己跟着教程的思路写了一段代码
#include<iostream>
#include<string>
using namespace std;
class JieGay;
class MyHouse
{
//成员函数做友元
friend void JieGay::visit();
public:
MyHouse()
{
mSittingRoom = "客厅";
mBedRoom = "卧室";
}
public:
string mSittingRoom;
private:
string mBedRoom;
};
class JieGay
{
public:
JieGay()
{
m = new MyHouse;
}
void visit()
{
cout << "杰哥正在访问:" << m->mSittingRoom << endl;
cout << "杰哥正在访问:" << m->mBedRoom << endl;
}
MyHouse* m;
};
void test01()
{
JieGay jie;
jie.visit();
}
int main()
{
test01();
system("pause");
}
运行后报错
虽然提前定义了JieGay,但是并没有写实现,因而报错,且一并导致MyHouse中的友元声明失效,JieGay类中的visit()无法访问MyHouse的私有成员。
于是将代码改成
#include<iostream>
#include<string>
using namespace std;
class MyHouse;
class JieGay
{
public:
JieGay()
{
m = new MyHouse;
}
void visit()
{
cout << "杰哥正在访问:" << m->mSittingRoom << endl;
cout << "杰哥正在访问:" << m->mBedRoom << endl;
}
MyHouse* m;
};
class MyHouse
{
//成员函数做友元
friend void JieGay::visit();
public:
MyHouse()
{
mSittingRoom = "客厅";
mBedRoom = "卧室";
}
public:
string mSittingRoom;
private:
string mBedRoom;
};
void test01()
{
JieGay jie;
jie.visit();
}
int main()
{
test01();
system("pause");
}
结果还是报错
不管这两个类的顺序如何,总会有一个未定义报错,且JieGay始终无法访问到MyHouse的私有成员 杰哥不要啦~
错因
对着教程又仔细看了一遍,发现自己跟教程唯一的不同就是教程的成员函数是在类外实现的,而我写的是在类内实现。
于是乎将代码改为
#include<iostream>
#include<string>
using namespace std;
class MyHouse;
class JieGay
{
public:
JieGay();
void visit();
MyHouse* m;
};
class MyHouse
{
//成员函数做友元
friend void JieGay::visit();
public:
MyHouse();
string mSittingRoom;
private:
string mBedRoom;
};
//类外实现MyHouse构造函数
MyHouse::MyHouse()
{
mSittingRoom = "客厅";
mBedRoom = "卧室";
}
//类外实现JieGay构造函数
JieGay::JieGay(
{
m = new MyHouse;
}
//类外实现JieGay成员函数
void JieGay::visit()
{
cout << "杰哥正在访问:" << m->mSittingRoom << endl;
cout << "杰哥正在访问:" << m->mBedRoom << endl;
}
void test01()
{
JieGay jg;
jg.visit();
}
int main()
{
test01();
system("pause");
}
果然不报错了,JieGay也可以顺利访问到MyHouse的私有成员 让我康康!
反思
仔细想了一下,前后区别只是编译的顺序不同,编译器是从上往下编译的,如果在类内就实现成员函数,编译的时候必然会出现一方未定义的情况,而如果改为类外实现,则可以随意控制函数编译顺序,让前置类型先编译出来。
虽然之前也学过类外实现的写法,但嫌麻烦一直没用,今天总算是明白类外实现的好处了。。。