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; } ); }