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

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

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

  1. class A {
  2. private:
  3. class B;
  4. std::set<B> b_set;
  5. };

.cpp:

  1. class A::B {
  2. };

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

bvuwiixz

bvuwiixz1#

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

  1. #include <set>
  2. class A {
  3. private:
  4. class B{
  5. B() : foo(1) { }
  6. int foo;
  7. };
  8. std::set<B> b_set;
  9. };

但是,如果你想分离你的定义和示例化,你可以这样做:
A. h

  1. #include <set>
  2. class A {
  3. private:
  4. class B {
  5. public:
  6. B();
  7. private:
  8. int someMethod();
  9. int foo;
  10. };
  11. std::set<B> b_set;
  12. };
    • A. cpp**
  1. #include "A.h"
  2. A::B::B() : foo(1) { }
  3. int A::B::someMethod() {
  4. return 42;
  5. }

一般来说,嵌套类可能是一个严重的PITA,因为要访问它们中的任何内容,您必须跳过所有的环节。
关于嵌套类的另一个很好的参考:Nested class definition in source file

展开查看全部
ss2ws0br

ss2ws0br2#

好吧,我迟到了,我知道,但我想指出另一种可能性,如果你想完全隐藏B类的内部:

  1. class A
  2. {
  3. private:
  4. class B;
  5. std::set<B*> b_set;
  6. };

注意在集中使用指针。然而,还有一个重要的区别:由于只插入指针,所以仍然可以插入指向具有相同内容的不同示例的指针。要解决这个问题,你需要一个自定义的比较器:

  1. class A
  2. {
  3. private:
  4. class B;
  5. struct Less
  6. {
  7. bool operator() (B const* x, B const* y) const
  8. {
  9. return *x < *y;
  10. }
  11. };
  12. std::set<B*, Less> b_set;
  13. };

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

  • A.h*
  1. #include <set>
  2. class A
  3. {
  4. private:
  5. class B;
  6. struct Less
  7. {
  8. bool operator() (B const* x, B const* y) const;
  9. };
  10. std::set<B*, Less> b_set;
  11. };
  • A.cpp*
  1. class A::B
  2. {
  3. friend bool Less::operator() (B const* x, B const* y) const;
  4. bool operator<(B const& other) const
  5. {
  6. return foo < other.foo;
  7. }
  8. int foo;
  9. };
  10. bool A::Less::operator() (B const* x, B const* y) const
  11. {
  12. return *x < *y;
  13. }

这允许将B完全隐藏在标头之外,如果您想要或出于任何原因需要这样做。但是,您不能再直接从堆栈中插入对象,因为它们不会被复制,而且您的指向堆栈的指针很快就会失效。在删除不再需要的对象时必须特别小心,否则会导致内存泄漏。请记住,Java中没有垃圾收集。如果使用C++11,可以在::std::auto_ptr之前使用::std::unique_ptr来缓解此问题:

  • 啊 *
  1. #include <set>
  2. #include <memory>
  3. class A
  4. {
  5. private:
  6. class B;
  7. struct Less
  8. {
  9. bool operator() (B const* x, B const* y) const;
  10. };
  11. std::set<std::unique_ptr<B>, Less> b_set;
  12. };
展开查看全部

相关问题