在集合中使用嵌套类时出现不完整类型错误

时间:2014-03-31 18:39:56

标签: c++ nested-class incomplete-type

我正在努力将一些Java代码翻译成C ++。当我尝试编写如下代码时:

·H:

class A {
  private:
    class B;
    std::set<B> b_set;
};

的.cpp:

class A::B {
};

我收到了一个不完整的类型错误。我理解这是因为嵌套类在b_set中使用之前是不完整的。但是解决它的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

您可以在B文件中描述整个.h课程。

这是一个有效的例子。

#include<set>
class A {
  private:
    class B{
        B():foo(1){}
        int foo;
    };
    std::set<B> b_set;
};

但是,如果要分离定义和实例化,可以执行以下操作:

<强> A.H

#include<set>
class A {

  private:
    class B{
      public:
      B();
      private:
      int someMethod();
      int foo;
    };
    std::set<B> b_set;
};

<强> A.cpp

#include "A.h"
  A::B::B():foo(1){}
  int A::B::someMethod(){
    return 42;
  }

一般来说,嵌套类可能是一个严肃的PITA,因为你需要跳过所有的箍来访问它们。

关于嵌套类的另一个很好的参考:Nested class definition in source file

答案 1 :(得分:2)

嗯,我迟到了,我知道,如果你想彻底隐藏B类的内部,我还是想指出另一种可能性:

class A
{
  private:
  class B;
  std::set<B*> b_set;
};

注意使用集合中的指针。但是,仍然存在一个重要区别:由于只插入了指针,您仍然可以将指针插入到具有相同内容的不同实例中。要解决此问题,您需要一个自定义比较器:

class A
{
  private:
  class B;
  struct Less
  {
    bool operator() (B const* x, B const* y) const
    {
      return *x < *y;
    }
  };
  std::set<B*, Less> b_set;
};

请注意(前面的答案中没有提到,但在那里也是必需的!)必须为B定义一个比较器(B或引用 not 指针!):

A.H

#include <set>
class A
{
  private:
  class B;
  struct Less
  {
    bool operator() (B const* x, B const* y) const;
  };
  std::set<B*, Less> b_set;
};

A.cpp

class A::B
{
  friend bool Less::operator() (B const* x, B const* y) const;
  bool operator<(B const& other) const
  {
    return foo < other.foo;
  }
  int foo;
};

bool A::Less::operator() (B const* x, B const* y) const
{
  return *x < *y;
}

如果您因任何原因需要或需要,可以将B完全隐藏在标题之外。但是,您不能再直接从堆栈中插入对象,因为它们不会被复制,并且您有快速无效的堆栈指针。在不再需要对象时,必须特别注意删除对象,否则会导致内存泄漏。请记住,Java中没有垃圾收集。如果使用C ++ 11,你可以使用:: std :: unique_ptr,:: std :: auto_ptr:

来缓解这个问题

A.H

#include <set>
#include <memory>
class A
{
  private:
  class B;
  struct Less
  {
    bool operator() (B const* x, B const* y) const;
  };
  std::set<std::unique_ptr<B>, Less> b_set;
};