簡體   English   中英

模板化的多態性通過非模板化的基類

[英]templated polymorphism via a non-templated base class

我有以下情況:

class Base2
{
};

class Base1
{
    virtual void f()=0;
protected:
    boost::shared_ptr<Base2> base2Ptr;
};


class Derived1 : public Base1
{
    Base1(boost::shared_ptr<Base2> b2)  : base2Ptr(b2) { }

    void f()
    {
        /* Here I would like to know the derived type of base2Ptr */
    }
}

template<typename T>
class Derived2 : public Base2
{
    typedef T result_type;
}

Derived1<T>::f()沒有任何方法可以從Base2*獲取typedef。

Derived2確實有一個typedef result_type ,但是從語言層面來看,沒有辦法保證Base2一個單獨的子類也有一個名為result_type的typedef。 C ++是一種靜態類型語言,因此您無法編寫依賴於可能根據Base2*的子類類型動態更改的類型的代碼。

(我在ideone添加了一些代碼(編輯為有一些虛擬析構函數。這很重要,因為shared_ptr在示例中正確地破壞了DoublyDerived2。))

基於對該問題的評論,我認為最終的目標是Derived1的構造函數以某種方式“知道”並“記住”傳遞給Derived1構造函數的對象的靜態類型。 尤其是:

Derived2<string> *p = new DoublyDerived2<string>();
// static type of p is Derived2, not DoublyDerived
shared_ptr<Base1> x = something_that_creates_a_Derived1(p);

Derived1對象應該知道p的類型為Derived2,而不僅僅是Base2類型

假設這是對問題的正確理解,那么ideone上的代碼應該解決它。 主要技巧是make_Derived1是一個模板,在創建Derived1時使用推導類型。 Derived1本身就是一個模板,它確保其foo方法知道類型。

template <class T>
shared_ptr<Base1> make_Derived1(shared_ptr<T> ptr) {
    cout << typeid(ptr).name() << endl;
    return shared_ptr<Base1>(new Derived1<T>(ptr));
}

和用法:

int main() {
    shared_ptr< Derived2<string> > p ( new DoublyDerived2<string>() ) ;
    shared_ptr<Base1> x = make_Derived1(p);
    x->f(); // prints something like "Derived2", as desired.
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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