【问题标题】:mutually referential classes yield "incomplete type" error相互引用的类产生“不完整类型”错误
【发布时间】:2011-04-28 02:13:18
【问题描述】:

我有一种情况,A 引用了在 B 中定义的类 C,而 C 有一个类 B 的实例。

当我尝试编译下面的代码时,我得到“field a has incomplete type”。我认为这是因为编译器不知道它应该为 A 的实例分配多少内存。

class A;

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

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

但是当我尝试编译它时,我得到“C in class B does not name a type”:

class B;
class B::C;

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


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

如何让编译器相信B::C 是一个真实类型?

【问题讨论】:

    标签: c++ class oop scope g++


    【解决方案1】:

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

    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!
    };
    

    这很可能是非法的,但我认为值得一试。如果它不起作用,那么我看不到任何解决问题的方法。

    【讨论】:

    • 我不相信这会编译,A 的默认构造函数不会初始化对 C 的引用。但是,要使上述工作正常,您只需要初始化 C 的构造函数A 本身 - 但是您有两个不同的 A 实例,也许这就是您所需要的? (@j_random_hacker,如果您在回答中暗示这一点,我们深表歉意!)
    • @Nim:仔细想想,你是对的。更新。 (虽然技术上的问题是 A 没有默认 ctor,因为给出了用户定义的 ctor——而不是它有一个错误的默认 ctor 无法初始化 c。)
    • @j_random_hacker:即使你定义了一个默认构造函数,你也必须以某种方式初始化对 C 的引用。我可以想到一种方法,你可以在你的类中拥有一个引用成员,但是如果默认构造,没有那个引用...使用 boost::variant c,而不是原始的 const B::C& c。使用该变体还可以让您在使用它之前测试是否有有效的参考......如果有兴趣,我将在下面发布完整代码作为完整答案......
    • @Nim:是的,那将是另一种解决方法。尽管我个人更喜欢在存在引用成员的情况下避免使用默认 ctor——这样你就知道它总是被初始化的。如果我想要类似的东西可以初始化或不初始化,我会使用指针。
    【解决方案2】:

    A 的前向声明没有任何作用:您不能声明不完整类型的实例。

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

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

    【讨论】:

    • 如果必须,我可以这样做,但是在我编写的代码中,将 C 嵌套在 B 中更有意义。C++ 不允许我声明是否有充分的理由嵌套不完整类型?或者这只是语言的一个怪癖?
    • @Andrew:看来你可以做到这一点(见 j_random_hacker 的回答)。复杂性是否值得......我想嵌套类型的另一个原因是修饰类名 - 然而,命名空间是一个专用工具。
    猜你喜欢
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 2011-04-29
    相关资源
    最近更新 更多