两个模板类由彼此的成员组成

时间:2013-04-25 02:21:52

标签: c++ templates g++

我的代码中需要两个模板类由彼此的成员字段组成。例如,我有两个文件,

templates.h

template <class T> class B;

template <class T>
class A
{
    B<A> a;

    // fields and methods dependent on T
};

template <class T>
class B
{
    A<B> b;

    // fields and methods dependent on T
};

的main.cpp

#include "templates.h"

int main()
{
    A<int> a;
}

编译时,我会收到此链接中显示的输出

http://pastebin.com/taBWZjar

我正在使用g ++编译器。当我输入g ++ --version时,我得到了

  

g ++(Gentoo 4.7.2 p1.3,pie-0.5.5)4.7.2

如果在c ++中无法做到这一点,那么替代方案或解决方法是什么?或者这可能是我的编译器的错误?

1 个答案:

答案 0 :(得分:7)

您当前的设计包含一个严重的缺陷,称为循环依赖。它永远不会编译,修复它的最佳方法是重新设计类层次结构。

为了告诉你为什么它永远无法编译,让我们通过删除模板简化情况:

class B;

class A {
  B b;
};

class B {
  A a;
};

现在尝试将其视为编译器。要知道分配类A需要多少空间(编译器必须知道 编译时),它需要知道多少空间分配课程B需要,反之亦然。显然,这是循环依赖。你可以尝试自己编译它,看看编译器抱怨它。

解决这个问题的一种可能方法是切换到指针(或引用):

class B;

class A {
  B* b; // B& b; is possible too
};

class B {
  A a;
};

这应该编译得很好。原因是现在编译器知道b是指针,并且容纳该指针所需的空间是固定的(32位目标为4个字节,相应地为64位目标为8个字节)。

注意:指向a B的指针/引用是不必要的,因为此时已定义A,因此我们可以将其用作B {{1}}中的直接成员。

在您的情况下,您使用模板进一步复杂化了,虽然您可以利用建议的修复(使用指针/引用)并将其与模板结合使用,但我不推荐它。您的代码必须完全重新设计。