C++ 相互引用的类产生“类”;“不完整类型”;错误

C++ 相互引用的类产生“类”;“不完整类型”;错误,c++,class,oop,scope,g++,C++,Class,Oop,Scope,G++,在这种情况下,a引用了B中定义的C类,C引用了B类的实例 当我试图编译下面的代码时,我得到“字段a的类型不完整””。我假设这是因为编译器不知道应该为一个实例分配多少内存 class A; class B { public: class C { A a; }; }; class A { A(const B::C& _c) : c(_c) {} const B::C& c; }; 但是当我试图编译它时,我得到“B类中的C没有命名类型”: 我

在这种情况下,a引用了B中定义的C类,C引用了B类的实例

当我试图编译下面的代码时,我得到“
字段a的类型不完整”
”。我假设这是因为编译器不知道应该为一个实例分配多少内存

class A;

class B {
public:
  class C {
    A a;
  };
};

class A {
  A(const B::C& _c) 
    : c(_c)
  {}
  const B::C& c;
};
但是当我试图编译它时,我得到“
B类中的C没有命名类型”


我怎样才能使编译器相信
B::C
是一个实类型?

对于
a
的正向声明没有任何作用:您不能声明一个不完整类型的实例

至于
B::C
,我认为不能在不完整的类型中使用嵌套名称。只是不要将
C
嵌套在
B
中:据我所知,这不会给您带来任何显著的优势*并阻止您向前声明它


*我能想到的唯一好处是,你可以在私有部分定义它,但是
A
首先与它无关。

作为一个绝对的猜测,我注意到有一种排列你没有尝试过:

class B {
public:
  class C; // Forward declaration
};

class A {
  A(const B::C& _c) 
    : c(_c)
  {}
  const B::C& c;
};

class B::C {
  A a;
  C() : a(*this) {}    // Thanks Nim for pointing this out!
};

这很可能是违法的,但我认为值得一试。如果它不起作用,那么我就没办法解决这个问题。如果我必须这样做,我可以做到,但是在我编写的代码中,C在B.嵌套更合理,C++有没有一个很好的理由不允许我声明嵌套的不完整类型?或者这只是语言的一个怪癖?@Andrew:看来你能做到(见j_random_hacker的答案)。这并发症是否值得。。。我猜嵌套类型的另一个原因是为了修饰类名-但是,命名空间是专门用于此目的的工具。我不相信这会编译,a的默认构造函数不会初始化对C的引用。但是,为了使上述功能正常工作,您所需要的只是C的构造函数来初始化A本身-但是您有两个不同的A实例,也许这就是您所需要的?(@j_random_hacker,如果你在回答中暗示了这一点,我深表歉意!)尼姆:想想看,你是对的。更新。(虽然技术上的问题是,
A
没有默认的构造函数,因为用户定义了一个构造函数——并不是说它有一个错误的默认构造函数,无法初始化
c
)@j\u random\u hacker:即使你定义了默认构造函数,您必须以某种方式初始化对C的引用。我可以想出一种方法,在您的类中可以有一个引用成员,但如果默认构造,则不需要该引用。。。使用boost::variant c,而不是原始常量B::c&c。在使用变量之前,您还可以测试是否存在有效的引用。。。如果有兴趣,我会把完整的代码作为完整的答案贴在下面…@Nim:是的,那将是另一种解决方法。虽然我个人更喜欢避免在引用成员存在时使用默认的ctor,这样你就知道它总是初始化的。如果我想要类似的东西,可以初始化或不初始化,我会使用指针。
class B {
public:
  class C; // Forward declaration
};

class A {
  A(const B::C& _c) 
    : c(_c)
  {}
  const B::C& c;
};

class B::C {
  A a;
  C() : a(*this) {}    // Thanks Nim for pointing this out!
};