我正在编写一个跨平台的类层次结构,并希望将依赖于平台的实现保留在它们自己的类中(而不是让一个类具有 #ifdefs
)。这是我目前所拥有的,但编译器提示 BaseDef
是私有(private)的。非常感谢任何有关如何在编译时保持此基本结构的帮助:-)
编辑: 它似乎来自 here这是不可能的。我可以通过任何其他方式保持这种通用结构并仍然可以编译吗?
根.h
class Root {
private:
class BaseDef {
virtual void foo() = 0;
virtual void bar() = 0;
};
#ifdef _WIN32
class WinImp;
#else
class NixImp;
#endif
BaseDef* imp;
BaseDef* getImp();
public:
Root() : imp(getImp()) {}
void foo();
void bar();
};
根.cpp
#include "Root.h"
void Root::foo() {
imp->foo();
}
void Root::bar() {
imp->bar();
}
WinImp.h
#ifdef _WIN32
#include "Root.h"
class WinImp : public Root::BaseDef {
public:
void foo();
void bar();
};
#endif
WinImp.cpp
#include "WinImp.h"
#ifdef _WIN32
Root::WinImp::foo() {
}
Root::WinImp::bar() {
}
Root::BaseDef* Root::getImp() {
return new Root::WinImp();
}
#endif
最佳答案
您的主要问题是 BaseDef
是私有(private)的。这意味着其他类(除了 Root 本身)无法访问 BaseDef
名称。一种方法是公开 BaseDef
。或者,您可以使派生类(WinImp
和 NixImp
)成为 Root
的好友,以便他们可以访问 BaseDef
姓名。此外 Root
无法访问 BaseDef
的成员,因此他们需要公开或使 Root
成为 BaseDef
的友元.
class Root {
private:
class BaseDef {
public:
// These need to be public so that Root can see them or Root needs to be a friend.
//Nothing else can see BaseDef though so this is safe.
virtual void foo() = 0;
virtual void bar() = 0;
};
class WinImp; // Forward declare the classes
friend class WinImp; // And then make them friends
class NixImp;
friend class NixImp;
BaseDef* imp;
BaseDef* getImp();
public:
Root() : imp(getImp()) {}
void foo();
void bar();
};
void Root::foo() {
imp->foo();
}
void Root::bar() {
imp->bar();
}
// Since this is a nested class i made it Root::WinImp
class Root::WinImp : public Root::BaseDef {
public:
void foo();
void bar();
};
void Root::WinImp::foo() {}
void Root::WinImp::bar() {}
Root::BaseDef* Root::getImp() {
return new WinImp();
}
根据 2003 年标准 (11.4.p2),此方法是不允许的,但在 C++11(同一示例)中,它是明确允许的 (11.3.p2)。但是,即使在 2003 模式下,clang(经过 3.1 测试)也接受这一点。 gcc(4.7.2 测试)接受这一点(即使在 2003 模式下),只要派生类嵌套在同一个类内,但如果在类外则不接受。
关于C++ 有一个嵌套类继承自另一个嵌套类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14514349/