我正在把一些Java代码翻译成C++。当我尝试写代码时,像这样:.h:
class A { private: class B; std::set<B> b_set; };
.cpp:
class A::B { };
我得到了一个不完整的类型错误。我理解这是因为嵌套类在b_set中使用之前是不完整的。但最好的办法是什么?
b_set
bvuwiixz1#
您可以在.h文件中描述整个B类。这里有一个工作的例子。
.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; };
#include "A.h" A::B::B() : foo(1) { } int A::B::someMethod() { return 42; }
一般来说,嵌套类可能是一个严重的PITA,因为要访问它们中的任何内容,您必须跳过所有的环节。关于嵌套类的另一个很好的参考:Nested class definition in source file
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或引用,* 不是 * 指针!):
#include <set> class A { private: class B; struct Less { bool operator() (B const* x, B const* y) const; }; std::set<B*, Less> b_set; };
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; };
2条答案
按热度按时间bvuwiixz1#
您可以在
.h
文件中描述整个B
类。这里有一个工作的例子。
但是,如果你想分离你的定义和示例化,你可以这样做:
A. h
一般来说,嵌套类可能是一个严重的PITA,因为要访问它们中的任何内容,您必须跳过所有的环节。
关于嵌套类的另一个很好的参考:Nested class definition in source file
ss2ws0br2#
好吧,我迟到了,我知道,但我想指出另一种可能性,如果你想完全隐藏B类的内部:
注意在集中使用指针。然而,还有一个重要的区别:由于只插入指针,所以仍然可以插入指向具有相同内容的不同示例的指针。要解决这个问题,你需要一个自定义的比较器:
请注意(这在前面的答案中没有提到,但在那里也是必需的!),必须为B定义一个比较器(B或引用,* 不是 * 指针!):
这允许将B完全隐藏在标头之外,如果您想要或出于任何原因需要这样做。但是,您不能再直接从堆栈中插入对象,因为它们不会被复制,而且您的指向堆栈的指针很快就会失效。在删除不再需要的对象时必须特别小心,否则会导致内存泄漏。请记住,Java中没有垃圾收集。如果使用C++11,可以在::std::auto_ptr之前使用::std::unique_ptr来缓解此问题: