2015-10-31 59 views
0

已解决!从非模板类派生的模板类:访问派生类的通用变量

我想使用模板创建一个不同类型对象的数组。 因此,我有一个非模板类(Base),以及一个从Base类派生的模板类。

我想知道的是如何访问派生类的泛型值(T val)?

class Base{ 
public: 

    // a function returns T val, it will be implemented in Derived class 

    // EDIT : virtual function here 

}; 

template<class T> 
class Derived: public Base { 

public: 
    T val; 

    Derived(T x) { 
     val = x; 
    } 

    // implementation.. it returns val 

    // EDIT : Implementation of virtual function 
}; 

解决方案:的dynamic_cast,需要注意的是基类至少应该有一个虚函数。

Base *p[2]; 
p[0] = new Derived<int>(24); 
p[1] = new Derived<double>(82.56); 

int a = dynamic_cast<Derived<int>*>(p[0])->val;  // casts p[0] to Derived<int>* 
double b = dynamic_cast<Derived<double>*>(p[1])->val; // casts p[1] to Derived<double>* 

cout << a << endl; 
cout << b << endl; 
+0

为什么不能让基类模板化呢? – basav

+0

你不能从基类中获取派生类成员...所以,如果它接受参数,可以将它传递给基类 – basav

+0

我试图创建一个包含不同类型对象的数组。我试图创建一个'模板类'的数组,但我不得不这样指定它的类型: 派生 p [10]。但数组应该容纳任何类型的对象 – luo

回答

0

上次我检查,你不能从基类(非虚拟)获得派生类成员。

你可以用这种方式修改你的代码,因为你正在使用模板。类型和值在构造时传递给基类,然后你可以使用它。

template<typename T> 
class Base { 
    T ini; 
public: 
    Base(T arg){ini = arg;} 
    T ret(){return ini;} 
}; 

template<class T> 
class Derived: public Base<T> { 

public: 
    T val; 

    Derived(T x) : Base<T>(x) { 
     //Base(x); 
     val = x; 
    } 

    // implementation.. it returns val 
}; 

然后,您可以像往常一样实例化并使用它。

Derived<int> e(5);  
e.ret(); 
+0

是否有可能像下面的代码? Base * p [10]; p [0] = new Derived (5); – luo

+0

我得到一个错误:在'p'之前缺少模板参数 – luo

+0

@luo此解决方案将限制您的数组为'int'elements。看看基督徒对一个通用容器的评论。 –

0

它看起来像你想CRTP

的想法是访问基类中派生类的成员。请注意,您将无法包含它们的异构列表。

template<typename D> 
struct Base { 
    void doThings() { 
     // access the derived class getT function 
     auto var = static_cast<D&>(*this).getT(); 

     cout << var << endl; 
    } 
}; 

template<typename T> 
struct Derived : Base<Derived> { 
    T getT() { 
     return myT; 
    } 

private: 
    T myT; 
};