如何用没有头的共享基类解决循环类依赖?

Sr1*_*703 7 c++ circular-dependency c++11 visual-studio-2012

所以我正在创建一个涉及将矢量嵌套在另一个内部的项目,但该结构将无法编译.我认为这是循环依赖的情况,但我看到的所有修复似乎只适用于涉及头文件和单独翻译单元的代码.

#include <iostream>
#include <vector>

class A {
public:
    virtual ~A();
};

// The following forward declaration statements didn't solve the
// compiler error:
// class C;
// class C : public A;

class B : public A {
    std::vector<A*> Avector;    
public:
    void addC(C* Cin){Avector.push_back(Cin);}
    ~B();
};

class C : public A {
    std::vector<A*> Avector;        
public:
    void addB(B* Bin){Avector.push_back(Bin);}
    ~C();
};

int main() {
    B b;
    C c;
    b.addC(&c);
    c.addB(&b);
}
Run Code Online (Sandbox Code Playgroud)

我试着向前宣布

class C;
Class C : public A;
Run Code Online (Sandbox Code Playgroud)

但它似乎都没有用.

我得到的错误是:

\test\test\source.cpp(15): error C2061: syntax error : identifier 'C'
\test\test\source.cpp(15): error C2065: 'Cin' : undeclared identifier
Run Code Online (Sandbox Code Playgroud)

这种代码是否可实现?

πάν*_*ῥεῖ 7

"...但我见过的所有修补程序似乎只适用于涉及头文件和单独翻译单元的代码."

我完全同意像c ++中的Resolve循环依赖这样的流行问答并没有真正回答你如何在单个实现文件(标题或不标题)中处理这个问题的问题.

然而,恕我直言,它被认为是更好的做法(并且你可以通过这些指针获取),将标题和实现/定义中的类声明分离到它们自己的翻译单元中.
即使只使用标头(例如模板类)库,您应该考虑提供单独的类声明(没有内联代码),并在单独的源文件中提供实现,该文件包含在那里.

你的问题实际上在这里:

class B : public A {
    // ...
    void addC(C* Cin) { Avector.push_back(Cin); }
                   // ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // ...
};
Run Code Online (Sandbox Code Playgroud)

此时(即使使用前向声明class C;)编译器也不知道如何转换C*A*,因为缺少有关继承关系的信息(并且不能,不能像前面那样进行声明class C : public A;).

"这种代码是否可以实现?"

您可以在单个翻译单元/头文件中执行所有操作:

不要使用B's类声明来内联函数定义,而是应该在完全声明之后将其分开class C:

class C;

class B : public A {
    // ...
    void addC(C* Cin);
};

class C : public A {
    // ...
};

inline void B::addC(C* Cin) { Avector.push_back(Cin); }
Run Code Online (Sandbox Code Playgroud)

class Cclass B无论如何都会看到完整的声明(因为声明顺序).因此可以使用该实现

void addB(B* Bin) { Avector.push_back(Bin); }
Run Code Online (Sandbox Code Playgroud)

class C声明中.