为我的忽视而道歉。我无法弄清楚如何使用不同的源文件声明内部类的主体。我想要实现的是这样的:
source1.h:
class A {
class B;
}
source2.h:
class B {
//
}
source3.cpp://Implementation of A
source4.cpp://Implementation of B
额外:在这些声明中如何隐含A和B之间的友谊?
答案 0 :(得分:13)
只要A
的定义不依赖于B
是完整类型,这将有效。 (所以A
可以包含指向B
的引用或指针,但不包含实际的B
实例,因为编译器不知道为B
分配多少空间,直到它已经看到了B
的定义。)
在source2.h中,您将通过指定范围来定义您在source1.h中声明的类:
class A::B {
// ...
};
在source4.cpp中,您还需要指定范围。例如,如果B
的定义声明了一个不执行任何操作的无参数构造函数:
A::B::B() { }
它与定义任何其他类或类成员完全相同,您只需将A::
添加到B
以让编译器知道类的位置。
我已经写了complete and working example这种技术。
关于“友谊”,我假设它意味着访问类/对象成员,嵌套类在任何一个方向都没有特殊访问权限。 1 内部类无法访问外部类的任何成员除了通常可以访问的那些,并且相同的规则适用于另一个方向。如果希望内部类具有对外部类中声明的成员的完全访问权限,则需要向外部类添加显式的友元声明。
1 根据标准(ANSI / ISO C ++ 11.8.1:“在C ++ 03中也是如此”嵌套类的成员没有特殊访问权限 封闭类的成员......“)但是在C ++ 11中,子类隐含地是父类的朋友。有些编译器就像在父类中声明的隐式友谊一样,即使在C语言中也是如此++ 03,但这种行为不能被认为是可移植的。为了安全起见,请明确声明友谊。这对C ++ 03和C ++ 11都同样有效。
答案 1 :(得分:1)
当你的A类有一个成员B时,你需要在定义类A之前使类定义可见。你应该写:
// source1.h
#include "source2.h"
class A {
class B b;
};
当你只有一个引用或指向B类对象的指针时,前向声明是无效的。
// source1.h
class B;
class A {
class B *b;
};
通过这种方法,您可以在类中定义友谊。
此外,我建议使关系可见的文件的名称。