多个源文件来声明内部类和友谊

时间:2013-08-02 14:51:11

标签: c++

为我的忽视而道歉。我无法弄清楚如何使用不同的源文件声明内部类的主体。我想要实现的是这样的:

source1.h:

class A {
    class B;
}

source2.h:

class B {
//
}

source3.cpp://Implementation of A

source4.cpp://Implementation of B

额外:在这些声明中如何隐含A和B之间的友谊?

2 个答案:

答案 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;
};

通过这种方法,您可以在类中定义友谊。

此外,我建议使关系可见的文件的名称。