CRTP对派生中受保护的CTOR的访问

CRTP access to protected CTOR in derived

本文关键字:CTOR 访问 受保护 派生 CRTP      更新时间:2023-10-16

我在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构造函数。

这就是问题所在:使用CRTP,我希望Base能够添加一个create()方法,该方法可以访问Derived的CTOR,但不要求Derived声明与Base的友谊

一个糟糕的方法是做以下事情:

template<typename T>
struct unprotect : public T {
    static T *create(void) {
        return new unprotect;
    }
};

这将克服最初的问题,但它会阻碍(纯粹的)虚拟技术,很可能会引起一两个令人讨厌的惊喜。

有没有一种方法可以使最初的实施发挥作用?同样,我不想将基本友谊添加到派生。

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

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