通过基类指针获取子类类型

时间:2011-03-29 11:57:57

标签: c++ templates pointers types

鉴于类布局(Base-&gt; Derived; Base-&gt; Derived2),以及我将实例作为基类指针(Base* baseder2 = new Derived2)保存到派生类的事实,我想能够使用派生类型(类似sh = new TemplClass<Derived2>(baseder2))实例化TemplClass实例。下面的代码实例化  sh = new TemplClass<Base>(baseder2),由于fn function未在类Base中声明,导致编译错误。如何找出baseder2指针的派生类型,最好没有dynamic_cast?真实代码有很多Base后代,所以我想避免使用dynamic_cast的if语句。我正在调查boost :: type_traits,但是不要该怎么做,说实话。 模板函数template <typename T> BaseTemplClass* foo(T* t) 只是工厂对象的蹩脚借口。

最好的问候, dodol

class Base
{
public:
  virtual ~Base(){}
};

class Derived : public Base
{
public:
  virtual ~Derived(){}
  void function()
  {
    std::cout<<"This is Derived"<<std::endl;
  }
};

class Derived2 : public Base
{
public:
  virtual ~Derived2(){}
   void function()
  {
    std::cout<<"This is Derived2"<<std::endl;
  }
};

class BaseTemplClass
{
public:
  virtual void Print() =0;
};

template <class Tmodel>
class TemplClass : public BaseTemplClass
{
public:
  TemplClass(Tmodel* m)
  {
    model = m;
  }
  void Print()
  {
    model->function();
    std::cout << " TemplClass"<<typeid(model).name() << std::endl;
  }
  Tmodel *model;
};

template <typename T> BaseTemplClass* foo(T* t)
{
  BaseTemplClass* sh;
  std::cout << "FOO: "<<typeid(t).name() << std::endl;
  sh = new TemplClass<T>(t);
  return sh;
}


int main(int argc, char **argv) 
{
    Derived* der = new Derived;
    Derived2* der2 = new Derived2;
    Base* baseder2 = new Derived2;

    BaseTemplClass* sh = foo(der);
    sh->Print();
    delete sh;

    sh = foo(der2);
    sh->Print();
    delete sh;


    sh = foo(baseder2);
    sh->Print();
    delete sh;

    delete der;
    delete der2;
    delete baseder2;
    return 0;
}

3 个答案:

答案 0 :(得分:4)

function中使Base抽象更有意义,以便您不需要知道它是哪个派生类?

答案 1 :(得分:2)

这是不可能的。模板参数类型必须在编译时确定,但指针的实际类型只能在运行时确定。

答案 2 :(得分:1)

在你的情况下真的需要模板类吗?在给定的示例中,您可以将方法“function”添加到基类,并将其设置为虚拟。

但是如果您仍然需要模板类,可以使用以下内容:

class Base
{
public:
  virtual ~Base(){}
  virtual BaseTemplClass* createTemplClass() = 0;
};

class Derived : public Base
{
public:
  virtual ~Derived(){}
  void function()
  {
    std::cout<<"This is Derived"<<std::endl;
  }
  virtual BaseTemplClass* createTemplClass()
  {
    return new TemplClass<Derived>( this );
  }
};

class Derived2 : public Base
{
public:
  virtual ~Derived2(){}
  void function()
  {
    std::cout<<"This is Derived2"<<std::endl;
  }
  virtual BaseTemplClass* createTemplClass()
  {
    return new TemplClass<Derived2>( this );
  }
};


template <typename T> BaseTemplClass* foo(Base* t)
{
  BaseTemplClass* sh;
  std::cout << "FOO: "<<typeid(t).name() << std::endl;
  sh = t->createTemplClass();
  return sh;
}