首页 > 代码库 > C++中两个类互相引用的解决方法

C++中两个类互相引用的解决方法

一、问题描述

现在有两个类A和B需要定义,定义A的时候需要用到B,定义B的时候需要用到A。

二、分析

A和B的定义和调用都放在一个文件中肯定是不可以的,这样就会造成两个循环调用的死循环。

根本原因是:定义A的时候,A的里面有B,所以就需要去查看B的占空间大小,但是查看的时候又发现需要知道A的占空间大小,造成死循环。

解决方法1:

(1)写两个头文件A.h和B.h分别用于声明类A和B;

(2)写两个.cpp文件分别用于定义类A和B;

(3)在A和B的头文件中分别导入对方的头文件。

解决方法2:

(1)写两个头文件A.h和B.h分别用于声明类A和B;

(2)写两个.cpp文件分别用于定义类A和B;

(3)在A的头文件中导入B的头文件;

(4)在B的头文件中不导入A的头文件,但是用extern 的方式声明类A,并且,在B中使用A的时候要用指针的形式。

原理:在B中用指针调用A,那么在A需要知道B占空间大小时,去找到B的定义文件,虽然B的定义文件中并没有导入A的头文件,不知道A的占空间大小,但是在B中调用A用的指针的形式,B知道指针占4个字节,所以A也是知道B的占空间大小。总结:当需要用一个类,但是不导入一个类的头文件不知道这个类占空间的大小的时候,可以用extern声明这个类,并用指针调用这个类的方法。

三、C++示例

A的头文件A.h:

#ifndef _A
#define _A
#include "B.h"//A的头文件导入了B的头文件
//extern class B;

class A
{
private:
	int a;
	B objectb;<span style="font-family: Arial, Helvetica, sans-serif;">//A的头文件导入了B的头文件,在调用B的时候就可以不用指针</span>
public:
	A();
	int geta();
	void handle();
};

#endif _A


B的头文件B.h:

#ifndef _B
#define _B

//#include "A.h"//B的头文件没有导入A的头文件,需要有三个地方需要注意!
extern class A;//注意1:需要用extern声明A

class B
{
private:
	int b;
	A* objecta;//注意2:调用A的时候需要用指针
public:
	B();
	int getb();
	void handle();
};

#endif _B


A的定义文件A.cpp:

#include <iostream>
#include "A.h"

using namespace std;

A::A()
{
	this->a=100;
}

int A::geta()
{
	return a;
}

void A::handle()
{
	cout<<"in A , objectb.b="<<objectb.getb()<<endl;
}


B的定义文件B.cpp:

#include <iostream>
#include "B.h"
#include "A.h"<span style="font-family: Arial, Helvetica, sans-serif;">//注意3:在B.cpp里面导入A的头文件</span>

using namespace std;

B::B()
{
	this->b=200;
}

int B::getb()
{
	return b;
}

void B::handle()
{
	objecta=new A();
	cout<<"in B , objecta->a="<<objecta->geta()<<endl;
}


main.cpp:

#include <iostream>
#include <cstdlib>
#include "A.h"
//#include "B.h" <span style="font-family: Arial, Helvetica, sans-serif;">//因为A.h里面已经包含B.h,所以在此不需要导入B.h了。</span>

using namespace std;

void main()
{
	A a;
	a.handle();
	B b;
	b.handle();

	system("pause");
}

运行结果:


四、最简单方法

最简单的方法就是在A的头文件导入B的头文件,在B的头文件导入A的头文件,这时候有如下好处:(1)调用的时候不需要用指针;(2)不需要用extern。

C++中两个类互相引用的解决方法