![](/img/trans.png)
[英]polymorphism: non-templated base with templated derived class, using base pointer
[英]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.