[英]Template class override base class virtual function
考慮以下代碼:
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(); }
目標是能夠使用模板來實現專業化,但仍允許用戶使用基類接口進行工作,例如:
int a;
auto s = GetSpecialization(a);
auto p = s.allocate();
上面的代碼不起作用; 出於明顯的原因, s.allocate()
總是返回nullptr
。
我絕對需要GetSpecialization
函數來返回Base
非模板類,那么該如何處理呢?
Base
類的虛方法不能是純虛方法,因為否則它將變為抽象,並且將使GetSpecialization
處的編譯失敗。
解決此模式的最佳方法是什么? 使用C ++ 11嗎? 謝謝!
Base GetSpecialization(const int&){ return IntSpecialization(); }
您正在對上面的IntSpecialization
對象進行切片 。 為了使您的代碼正常工作, GetSpecialization
必須返回Base *
或Base&
。 例如,以下將按您的預期工作:
std::unique_ptr<Base> GetSpecialization(const int&)
{
return std::unique_ptr<Base>(new IntSpecialization());
}
為了使上面的代碼起作用,您需要向Base
添加一個virtual
析構函數。
class Base
{
public:
virtual void* allocate(){ return nullptr; }
virtual ~Base() = default;
};
否則,當unique_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 ); }
不太詳細的解決方案是使用std::function
和lambda
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; } ); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.