模板化的多态性通过非模板化的基类

时间:2012-01-08 18:22:27

标签: c++ templates polymorphism

我有以下情况:

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

2 个答案:

答案 0 :(得分:1)

Derived1<T>::f()无法从Base2*获取typedef。

Derived2中确实有一个typedef result_type,但从语言层面来看,无法保证Base2的单独子类也会有一个名为{{1的typedef }}。 C ++是一种静态类型语言,因此您无法编写依赖于可能根据result_type内的子类类型动态更改的类型的代码。

答案 1 :(得分:1)

(我在ideone上添加了一些代码(编辑为有一些虚拟析构函数。这很重要,因为shared_ptr在示例中正确地破坏了DoublyDerived2。)

基于对问题的评论,我认为最终的目标是让Derived1的构造函数以某种方式“知道”并“记住”传递给Derived1构造函数的对象的 static 类型。特别是:

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.
}