C++ 类 互相包含的问题研究

来源:互联网 发布:单机游戏制作软件 编辑:程序博客网 时间:2024/06/05 22:52

问题:

在一个项目中有两个类 A 和 B ,分别对应 四个 文件 A.h, A.cpp, B.h, B.cpp。内容如下:

A.h
#pragam once#include "A.h"class A{public:A();~A();int mI;int f();B* b;};



B.h
#pragam once#include "B.h"class B{public:B();~B();int mI;int f();A* a;};




A.cpp
#include "A.h"A::A(){<span style="white-space:pre"></span>mI = 10;}A::~A(){}int A::f(){<span style="white-space:pre"></span>return mI;}

B.cpp
#include "B.h"B::B(){<span style="white-space:pre"></span>mI = 20;}B::~B(){}int B::f(){<span style="white-space:pre"></span>return mI;}

注意其中 A.h,B.h 互相包含了。

编译.....妥妥的报错了。。


解决方案:

首先看看这个链接:
http://blog.csdn.net/tonywearme/article/details/8136530

查看一下预编译文件

A.i
#pragma once#pragma onceclass B{public:B();~B();A* a;};class A{public:A();~A();B* b;};A::A(){}A::~A(){}

B.i
#pragma once#pragma onceclass A{public:A();~A();B* b;};class B{public:B();~B();A* a;};B::B(){}B::~B(){}

这里可以看出问题,A, B 申明有个先后顺序,所以总有一个不能找到声明。并且还有可能造成重复定义。

接着我们就对症下药。

先看 A.h, 在其中有个 B 类型的指针,既然是指针类型,编译器就已经知道了,这个地方占用 4 个字节就行了, 我们只需要告诉编译器,有 B 这个类型即可,至于 B 里面包含了什么东西, 编译器 这时不必要知道,只是在 B 构造的那一刻, 才需要 B 里面是什么内容。  

我们改一下:

A.h
#pragma onceclass B;class A{public:A();~A();int mI;int f();B* b;};

B.h
#pragma onceclass A;class B{public:B();~B();int mI;int f();A* a;};

A.cpp
#include "A.h"#include "B.h"A::A(){mI = 10;}A::~A(){}int A::f(){b = new B();return b->f();}


B.cpp
#include "B.h"#include "A.h"B::B(){mI = 20;}B::~B(){}int B::f(){a = new A();return a->f();}



再编译一次 OK了。

接着 再看看预编译文件

A.i
#pragma onceclass B;class A{public:A();~A();int mI;int f();B* b;};#pragma onceclass A;class B{public:B();~B();int mI;int f();A* a;};A::A(){mI = 10;}A::~A(){}int A::f(){b = new B();return b->f();}



B.i
#pragma onceclass A;class B{public:B();~B();int mI;int f();A* a;};#pragma onceclass B;class A{public:A();~A();int mI;int f();B* b;};B::B(){mI = 20;}B::~B(){}int B::f(){a = new A();return a->f();}



至此,就可以使用A 和 B 了。

使用:

main.cpp

#include <iostream>#include "A.h"#include "B.h"int main(){A a;std::cout << a.f() << std::endl;system("pause");return 0;}

main.i
#pragma onceclass B;class A{public:A();~A();int mI;int f();B* b;};#pragma onceclass A;class B{public:B();~B();int mI;int f();A* a;};int main(){A a;std::cout << a.f() << std::endl;system("pause");return 0;}



0 0
原创粉丝点击