C++类相互包含
问题描述
两个类,Class A和Class B,定义时,Class A用到了Class B, Class B用到了Class A.
假设有两个类,如下
- ClassA.h
#include "ClassB.h"
class A
{
public:
int m_valueA;
B m_b;
}
- ClassB.h
#include "ClassA.h"
class B
{
public:
int m_valueB;
A m_a;
}
但是上面这种情况,在编译的时候,会出现错误,比如
B.h中使用了未知类型的Class A.
分析
在上述的情况下,编译器在编译的时候,Class A会包含Class B, 所以就去查看B的占用空间的大小,但是查看的时候,又发现需要知道A的占空间的大小。会出现A中包含B,B中包含A, A.B.A.B…无线循环的情况。
解决方法
- Class A
在Class A中声明Class B,但是不包含Class B的头文件
/*这是a.h头文件*/
#ifndef A_H
#define A_H
class B //注意:单纯的声明Class B;
class A
{
... //A的一些声明
B* m_b_ptr //注意:仅能在class A里使用class B的指针或者引用
}
#endif
- ClassB
在Class B中添加Class A的头文件
/*这是b.h头文件*/
#ifndef B_H
#define B_H
#include"A.h" //注意:声明A的头文件
class B
{
... //B的一些声明
A m__a_object //Class A对象, A的头文件导入了B的头文件,就可以不使用指针
A* m_a_ptr //Class A指针
}
#endif
原因
在A中用指针调用B,那么在A需要知道B占空间大小的时候,就会去找到B的定义文件,虽然A的定义文件中并没有导入B的头文件,不知道B的占用大小,但是由于在A中调用B的时候用的指针形式,A只知道指针占用4个字节就可以,不需要知道B真正占用空间大小。但是B中incude了A的头文件,所以B是知道A占用空间大小的。
注意:
A.h中包含B.h, B.h中包含A.h。编译时不能通过。
测试例程
- Class Person
#include <iostream>
#include <string>
#include "Phone.h" //注意:添加class Phone定义的头文件
using namespace std;
class Person
{
public:
Person(string personName, string phoneType)
{
m_Name = personName;
m_phone.setOwner(this);
cout << "Person and Phone constructure fun" << endl;
cout << "Person object address: " << m_phone.getPersonPtr() << endl;
cout << "Person object this address: " <<this << endl;
}
~Person()
{
cout << "This is de-constructure fun" << endl;
}
string m_Name; //person Name
Phone m_phone; //注意,这里可以直接使用Phone的定义而非指针
}
- Class Phone
#include <iostream>
#include <string>
using namespace std;
class Person; //注意,这里只需要声明Person, 在Phone.h中不包含Person.h
class Phone
{
public:
Phone();
{
cout << "this is phone default constructure fun" << endl;
}
~Phone()
{
cout << "this is phone de-constructure fun" << endl;
}
Phone(string name);
void setOwner(Person *personPtr) //设置属于哪个Person
{
if (personPtr!=NULL)
{
m_personPtr = personPtr;
}
}
Person *getPersonPtr(void)
{
return m_personPtr;
}
string m_phoneName;
private:
Person *m_personPtr;
};
- test函数
#include "Person.h"
int main()
{
Person p("Zhang San", "Sumsun");
system("Pause");
return 0;
}
测试结果
可以看到Class Phone中的指向Person的指针,和当前Person对象内部的this指针的值相同。