我确信这是我的一些设计缺陷,主要是因为我有Java背景。但事实就是如此。
下面是一般的设置:
我有一个关于#include "B.h"的课程,比如说A
#include "B.h"
class A {
// stuff
private:
B _b;
}此外,我还用#include "C.h"编写了B类
#include "C.h"
class B {
// more stuff
private:
C::EnumType _cEnum;
}最后,我用#include "A.h"实现了C类
#include "A.h"
class C {
public:
C(A a);
enum EnumType {
// enum stuff
};
// more stuff
}我该如何解决这个问题呢?我已经尝试了一些关于转发声明的业务,但它似乎不起作用,尽管我并不声称我做得正确。也许是命名空间?
发布于 2012-02-11 22:39:04
我尝试过一些使用转发声明的业务,但似乎不起作用
您没有向我们展示什么“似乎不起作用”,或者以什么方式“看起来不起作用”,但是在您的代码中有一个地方可以用正向声明替换完整的类型定义,还有两个地方不能。
你做不到的地方
非静态数据成员必须是完整类型:
[C++11: 9.2/10]:非static(9.4)数据成员的类型不能不完整。特别是,类C不应包含类C的非静态成员,但它可以包含指向类C的对象的指针或引用。
因此,不能向前声明A中的B和B中的C::EnumType。
BTW:这不是static数据成员的情况,它可以向前声明:
[C++11: 9.4.2/2]:static数据成员在其类定义中的声明不是定义,可能是cv限定的void以外的不完整类型。
你能做到的地方
但是,成员函数声明中的参数类型并非如此,因此可以在C(A a)中转发声明A
class A;
class C {
public:
C(A a);
enum EnumType {
// enum stuff
};
// more stuff
};尽可能少的#include到头文件中。
为什么你不需要
我敢肯定这是我的一些设计缺陷,主要是因为我来自
背景
我看不出Java与它有什么关系,但是,是的,您的设计似乎有缺陷,因为这些类都是相互依赖的。也许C::EnumType应该改为B::EnumType?试着让你的类更加自包含。正向声明都很好,但是如果你解决了设计紧密耦合的根本问题,生活会容易得多。
发布于 2012-02-11 22:47:12
在C中,你不需要包含A,只有另外两个头文件需要你放在那里的include指令。
class A;
class C {
public:
C(A a);
enum EnumType {
// enum stuff
};
// more stuff
};将C::C的定义放入.cpp文件中,然后可以在其中包含A.h。只有C::C的定义需要它的参数类型有定义。
发布于 2012-02-11 22:45:28
@Lightness说-如果你使用'forward‘定义声明类A,你不需要把a.h包含到C的编译单元中。只需将'class A;‘放到头文件中,它会告诉编译器(和链接器)在以后找出A是什么。这样做的唯一缺点是文件C不再知道A的内部是什么,因此您必须使用引用或指针。
另一种方法是将C分成两部分。有没有什么原因将枚举嵌入其中,而不是B的一部分?如果C和B共享枚举定义,那么它应该被分成一个单独的类,或者仅仅是一个顶级的枚举。
当我得到像这样的循环定义时,我会仔细检查我在做什么。我总是发现我把事情搞得太复杂了。
https://stackoverflow.com/questions/9241007
复制相似问题