类的循环依赖问题
面试一个苏州的研究院遇到的提问,当时并不知道咋回事,记录一下。
类的循环依赖问题,即A类拥有B类的对象b作为数据成员,B类则有A类的对象作为数据成员。
class A
{
public:
A();
virtual ~A();
protected:
private:
B b;
};
class B
{
public:
B();
virtual ~B();
protected:
private:
A a;
};
此时编译则会报错:||=== 生成: Debug in 类的循环依赖 (compiler: GNU GCC Compiler) =|
include\A.h|15|error: ‘B’ does not name a type|
E:\Cpp__CodeBlocksWorlSpace\类的循环依赖\src\A.cpp||In destructor ‘virtual A::~A()’:
E:\Cpp__CodeBlocksWorlSpace\类的循环依赖\src\A.cpp|10|error: ‘b’ was not declared in this scope|
||= Build 失败了: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
因为两个类存在相互的调用,无法为类分配具体的空间。
看到别人的建议可以将对象声明为指针,则可以编译通过,因为指针的大小是确定的(一般4字节),则类的大小可以确定,但我试了一下,还是报错。
||=== 生成: Debug in 类的循环依赖 (compiler: GNU GCC Compiler) =|
include\A.h|15|error: ‘B’ does not name a type|
E:\Cpp__CodeBlocksWorlSpace\类的循环依赖\src\A.cpp||In destructor ‘virtual A::~A()’:
E:\Cpp__CodeBlocksWorlSpace\类的循环依赖\src\A.cpp|10|error: ‘b’ was not declared in this scope|
||= Build 失败了: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
解决办法是增加前向引用声明。
在使用一个类之前,必须定义该类;前向引用声明是在引用未定义的类之前,将该类的名字告诉编译器,使编译器知道那是一个类名。但尽管使用了前向引用声明,但是在提供一个完整的类定义之前,不能定义该类的对象,也不能在内联成员函数中使用该类的对象。
class B;
class A
{
public:
A();
virtual ~A();
protected:
public:
B *b;
};
class A;
class B
{
public:
B();
virtual ~B();
protected:
public:
A *a;
};
注意:此时对象仍然是指针,不用指针则会提示A和B时不完整的类
编译通过: