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

vatpfxk5  于 2023-06-25  发布在  其他
关注(0)|答案(2)|浏览(155)

我正在把一些Java代码翻译成C++。当我尝试写代码时,像这样:
.h:

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

.cpp:

class A::B {
};

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

bvuwiixz

bvuwiixz1#

您可以在.h文件中描述整个B类。
这里有一个工作的例子。

#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

ss2ws0br

ss2ws0br2#

好吧,我迟到了,我知道,但我想指出另一种可能性,如果你想完全隐藏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或引用,* 不是 * 指针!):

  • 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::auto_ptr之前使用::std::unique_ptr来缓解此问题:

  • 啊 *
#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;
};

相关问题