C++ 模板类重写基类虚函数

C++ 模板类重写基类虚函数,c++,templates,c++11,overriding,virtual,C++,Templates,C++11,Overriding,Virtual,考虑以下代码: class Base { public: virtual void* allocate(){ return nullptr; } }; template <class T> class BaseTemplate : public Base { public: void* allocate() override { return new T(); } }; class IntSpecialization : public BaseTemplate&l

考虑以下代码:

class Base
{
public:
    virtual void* allocate(){ return nullptr; }
};

template <class T> class BaseTemplate : public Base
{
public:
    void* allocate() override { return new T(); }
};

class IntSpecialization : public BaseTemplate<int>
{
};

Base GetSpecialization(const int&){ return IntSpecialization(); }
上述代码不起作用
s.allocate()
总是返回
nullptr
,原因显而易见

我绝对需要
GetSpecialization
函数来返回
Base
非模板类,那么我该怎么做呢

Base
类虚拟方法不能是纯的,因为否则它会变得抽象,并且在
GetSpecialization
处编译失败

解决这种模式的最佳方法是什么?使用C++11? 谢谢

您就是上面的
IntSpecialization
对象。要使代码正常工作,
GetSpecialization
必须返回
Base*
Base&
。例如,以下内容将按照您的预期工作:

std::unique_ptr<Base> GetSpecialization(const int&)
{ 
    return std::unique_ptr<Base>(new IntSpecialization()); 
}
否则,当
unique\u ptr
超出范围时,它将调用
delete ptr
,其中
ptr
的类型是
Base*
,通过基类指针多态删除派生类对象是未定义的行为,除非基类析构函数是
虚拟的

您就是上面的
IntSpecialization
对象。要使代码正常工作,
GetSpecialization
必须返回
Base*
Base&
。例如,以下内容将按照您的预期工作:

std::unique_ptr<Base> GetSpecialization(const int&)
{ 
    return std::unique_ptr<Base>(new IntSpecialization()); 
}

否则,当
unique\u ptr
超出范围时,它将调用
delete ptr,其中
ptr
的类型是
Base*
,通过基类指针多态删除派生类对象是未定义的行为,除非基类析构函数是
virtual

仅使Base具有指向BaseTemplate的指针:

class BaseInterface {
public:
    virtual void* allocate() = 0;
}

class Base
{
   std::unique_ptr<BaseInterface> interface;
public:
    Base( BaseInterface *i ) : interface( i ) {}
    void* allocate(){ return interface->allocate(); }
};

template <class T> class BaseTemplate : public BaseInterface
{
public:
    void* allocate() override { return new T(); }
};

class IntSpecialization : public BaseTemplate<int>
{
};

Base GetSpecialization(const int&){ return Base( new IntSpecialization ); }

只需使Base具有指向BaseTemplate的指针:

class BaseInterface {
public:
    virtual void* allocate() = 0;
}

class Base
{
   std::unique_ptr<BaseInterface> interface;
public:
    Base( BaseInterface *i ) : interface( i ) {}
    void* allocate(){ return interface->allocate(); }
};

template <class T> class BaseTemplate : public BaseInterface
{
public:
    void* allocate() override { return new T(); }
};

class IntSpecialization : public BaseTemplate<int>
{
};

Base GetSpecialization(const int&){ return Base( new IntSpecialization ); }

您是否也可以执行
返回{new IntSpecialization()}
?@0x499602D2
唯一的ptr(T*)
构造函数是
显式的
,因此复制列表初始化将失败。@T.C.因为他的
没有
虚拟的
析构函数。我应该在答案中加上这一点。@Praetorian的观点很好,但你的代码随后将其结构移动到一个
std::unique\u ptr
…这不是违背了目的吗?@t.C.我只是想看看它是否真的有效。我假设,由于我正在从
唯一\u ptr
构建
唯一\u ptr
,前者将复制/移动删除器,并使用
default\u delete
删除对象,但我错了。再次更新答案的时间到了。您是否也可以执行
返回{new IntSpecialization()}
?@0x499602D2
唯一的ptr(T*)
构造函数是
显式的
,所以复制列表初始化将失败。@T.C.因为他的
没有
虚拟的
析构函数。我应该在答案中加上这一点。@Praetorian的观点很好,但你的代码随后将其结构移动到一个
std::unique\u ptr
…这不是违背了目的吗?@t.C.我只是想看看它是否真的有效。我假设,由于我正在从
唯一\u ptr
构建
唯一\u ptr
,前者将复制/移动删除器,并使用
default\u delete
删除对象,但我错了。是时候再次更新答案了。
class BaseInterface {
public:
    virtual void* allocate() = 0;
}

class Base
{
   std::unique_ptr<BaseInterface> interface;
public:
    Base( BaseInterface *i ) : interface( i ) {}
    void* allocate(){ return interface->allocate(); }
};

template <class T> class BaseTemplate : public BaseInterface
{
public:
    void* allocate() override { return new T(); }
};

class IntSpecialization : public BaseTemplate<int>
{
};

Base GetSpecialization(const int&){ return Base( new IntSpecialization ); }
class Base 
{
public:
    typedef std::function<void *()> creator;
    Base( const creator &c ) : cr( c ) {}
    void *allocate() { return cr(); }
private:
    creator cr;
};

template<class T>
Base GetSpecialization( const T & ) { return Base( []() { return new T; } ); }