CRTP访问受保护的CTOR派生

时间:2015-02-26 15:13:57

标签: c++

我查看了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友谊。

1 个答案:

答案 0 :(得分:0)

不幸的是,在C ++中你无法做你想做的事情。你要么必须在Derived中编写公共创建函数,要么允许它的构造函数是公共的(你在这里用受保护的构造函数解决了什么问题?)。

所有受保护的意思是派生类的this指针可用于访问父类的受保护成员。 授予子类对任意父类实例的任意受保护成员的任意访问权限(包括实例仅由new创建时)。