簡體   English   中英

模板類覆蓋基類虛函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM