c++中的正向声明VS编译顺序错误,以避免包含递归标头



我正在用c++编写一个由许多.h和.c文件组成的大型代码。

主要问题是由一对本应相互连接的类引起的。由于软件体系结构中的声明需要,第一个类(名称为A)在"上层"类中初始化。

所以我们得到了这样的东西:

#include A.h
class mainClass{
...
A a;
...
}

A.h看起来像:

#ifndef A_H
#define A_H
#include B.h
class A{
A();
fooA();
...
private:
B b;
...   
}
#endif

A.cpp看起来像:

#include B.h
#include A.h
...
A::A(){
...
b(this) //here I get the first error that follows
...
}
A::fooA(){//do somthing}

为了避免在第二个类中包含相互的头(让它是B),我使用了前向声明和指向类a的指针var。

B.h看起来像:

#ifndef B_H
#define B_H
class A; //Forward declaration to A
class B{
B()
B(A* const t)
fooB();
A* a;   //pointer to A object
}

B.cpp看起来像:

#include B.h  
B::B(){
//default constructor. Do Nothing
}
B::B(A* const t){
  this->a=t //constructor that set the pointer to the object of type A
}
B::fooB(){
   a->fooA(); //here i get the second error that follows
}

现在,如果在我的Makefile中,我在B之前链接了A,我会得到编译错误:

//First error. See code above for line numbers
error: no match for call to ‘(B) (A* const)’

另一方面,如果我在A之前链接B,我会得到编译错误:

//Second error. see code above for line numbers
error: invalid use of incomplete type ‘struct A’
_B.h:'line of the forward declaration': error: forward declaration of ‘struct A’

我必须承认,我对c++还很陌生,所以我不明白我错在哪里了。

编辑

现在我使用的解决方案是:

  1. 使用包括防护
  2. 正向声明类A,并且不将A.h包括在B.h中
  3. 在A.cpp和B.cpp中同时包含B.h和A.h。始终在A.h之前包含B.h

但我得到了同样的错误:

error: no match for call to ‘(B) (A* const)'

可能是构造函数重载问题吗?如果我删除线路

b(this)

编纂工作很好。

已解决

如果使用一个帮助函数来设置B中的变量a*a,而不是使用构造函数,那么在编译过程中一切都很好。也许我需要更好地理解C++中的构造函数重载。非常感谢。

  1. 使用包括防护
  2. 正向声明类A,并且不将A.h包括在B.h中
  3. 在A.cpp和B.cpp中同时包含B.h和A.h。始终在A.h之前包含B.h

尝试从B.cpp中包含"A.h"!

当你需要使用B.cpp中的A时,这将解析你的"A"类型。只需确保你什么都不做,只在B.h中保留一个指向A的指针/引用,并在B.cpp内使用A进行所有实际工作。

首先,遵循'us2012'的思想并使用include guards!

然后-更改正向声明:

A.h:

#ifndef A_H
#define A_H
class B;
class A{
   A();
   fooA();
   ...
private:
   B b;
   ...   
}
#endif

以及在A.cpp 中包含B.h

在B.h中,你再次包含A.h,但包含保护应该可以防止错误:

#ifndef B_H
#define B_H
#include "A.h"
class B{
  B()
  B(A* const t)
  fooB();
  A* a;   //pointer to A object
}
#endif

我还没有测试过。。。但它应该起作用。

最新更新