C ++中嵌套types/类的前向声明
我最近陷入了这样的情况:
class A { public: typedef struct/class {...} B; ... C::D *someField; } class C { public: typedef struct/class {...} D; ... A::B *someField; }
通常你可以声明一个类名:
class A;
但是你不能转发声明一个嵌套types,下面会导致编译错误。
class C::D;
有任何想法吗?
你不能这样做,这是C ++语言的漏洞。 您必须至less嵌套一个嵌套类。
class IDontControl { class Nested { Nested(int i); }; };
我需要一个前瞻性参考,如:
class IDontControl::Nested; // But this doesn't work.
我的解决方法是:
class IDontControl_Nested; // Forward reference to distinct name.
稍后我可以使用完整的定义:
#include <idontcontrol.h> // I defined the forward ref like this: class IDontControl_Nested : public IDontControl::Nested { // Needed to make a forwarding constructor here IDontControl_Nested(int i) : Nested(i) { } };
如果有复杂的构造函数或其他特殊的成员函数没有顺利inheritance,这种技术可能比它的价值更麻烦。 我可以想象某些模板魔法反应不好。
但在我这个非常简单的情况下,它似乎工作。
如果你真的想要避免#include头文件中令人讨厌的头文件,你可以这样做:
hpp文件:
class MyClass { public: template<typename ThrowAway> void doesStuff(); };
cpp文件
#include "MyClass.hpp" #include "Annoying-3rd-party.hpp" template<> void MyClass::doesStuff<This::Is::An::Embedded::Type>() { // ... }
但是之后:
- 你将不得不在调用时指定embeddedtypes(特别是如果你的函数没有使用embeddedtypes的任何参数)
- 你的function不能是虚拟的(因为它是一个模板)
所以,是的,权衡…
我不会说这个答案,但仍然是一个有趣的发现:如果你重复声明你的结构在一个名为C的名称空间,一切都很好(至less在gcc中)。 当C的类定义被发现时,它似乎默默覆盖了N空间C.
namespace C { typedef struct {} D; } class A { public: typedef struct/class {...} B; ... C::D *someField; } class C { public: typedef struct/class {...} D; ... A::B *someField; }
这将是一个解决方法(至less对于问题中描述的问题 – 不是针对实际问题,即不能控制C
的定义时):
class C_base { public: class D { }; // definition of C::D // can also just be forward declared, if it needs members of A or A::B }; class A { public: class B { }; C_base::D *someField; // need to call it C_base::D here }; class C : public C_base { // inherits C_base::D public: // Danger: Do not redeclare class D here!! // Depending on your compiler flags, you may not even get a warning // class D { }; A::B *someField; }; int main() { A a; C::D * test = a.someField; // here it can be called C::D }