我查看了stackoverflow,我没有看到我的确切问题,所以我发布了它。我用cxx03构建它,所以不允许使用cxx11 +功能。
我有以下简化说明:
template<typename T>
struct unprotect : public T {
static T *create(void) {
return new T;
}
};
template<class T>
struct Base
{
private:
public:
static T * Create(void) {
return unprotect<T>::create();
}
static void Destroy(T *p) {
delete p;
}
};
struct Derived : public Base<Derived>
{
protected:
Derived(void){}
};
int main(int argc,const char** argv)
{
Derived * d = Derived::Create();
Derived::Destroy(d);
return( 0 );
}
这会在g ++ v4.8中产生以下错误:
24)~/workspace/tricks $ g++ src/tricks.cpp
src/tricks.cpp: In instantiation of 'static T* unprotect<T>::create() [with T = Derived]':
src/tricks.cpp:14:37: required from 'static T* Base<T>::Create() [with T = Derived]':
src/tricks.cpp:29:28: required from here
src/tricks.cpp:24:5: error: 'Derived::Derived()' is protected
Derived(void){}
^
src/tricks.cpp:4:20: error: within this context
return new T;
我原以为,由于unprotect继承自T,unprotect :: create()可以访问派生类'protected constructor。
真的很简单:使用CRTP,我希望Base能够添加一个create()方法,该方法可以访问衍生的CTOR,但不需要Derived来声明友谊与基地。
糟糕的做法是做类似以下的事情:
template<typename T>
struct unprotect : public T {
static T *create(void) {
return new unprotect;
}
};
这将超越最初的问题,但它会对(纯粹的)虚拟产品不利,并且很可能会引起一两个令人讨厌的惊喜。
有没有办法让原始实现工作?同样,我不想要为Derived添加Base友谊。
答案 0 :(得分:0)
不幸的是,在C ++中你无法做你想做的事情。你要么必须在Derived
中编写公共创建函数,要么允许它的构造函数是公共的(你在这里用受保护的构造函数解决了什么问题?)。
所有受保护的意思是派生类的this
指针可用于访问父类的受保护成员。 不授予子类对任意父类实例的任意受保护成员的任意访问权限(包括实例仅由new
创建时)。