我正在编写一个跨平台的类层次结构,并希望将平台相关的实现保留在他们自己的类中(而不是让一个类具有#ifdefs
)。这是我到目前为止,但编译器抱怨BaseDef
是私有的。任何帮助我如何保持这个基本结构,同时让它编译将非常感激: - )
编辑:here似乎无法做到这一点。还有其他方法我可以保留这个通用结构并仍然编译吗?
Root.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();
};
ROOT.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
答案 0 :(得分:1)
抱怨BaseDef
是private
...
class Root {
private:
class BaseDef {
virtual void foo() = 0;
virtual void bar() = 0;
};
所以公开......
class Root {
public:
class BaseDef {
virtual void foo() = 0;
virtual void bar() = 0;
};
<强>脚注:强>
你试图避免#ifdef
,所以摆脱这个:
#ifdef _WIN32
class WinImp;
#else
class NixImp;
#endif
相反,只需使用一个类:
class Imp;
答案 1 :(得分:1)
您的主要问题是BaseDef
是私有的。这意味着其他类(除了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)。然而,clang(3.1测试)即使在2003模式下也接受这一点。 gcc(4.7.2已测试)接受此(即使在2003模式下),只要派生类嵌套在同一个类中,但如果在类之外则不会。