【问题标题】:get subclass type through the base class pointer通过基类指针获取子类类型
【发布时间】:2011-03-29 11:57:56
【问题描述】:

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

最好的问候, 多多尔

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

【问题讨论】:

  • 我现在意识到我的问题没有任何意义。我确实需要模板类,而这些功能确实必须是非虚拟的。我需要工厂方法。实现此目的的一种方法是将描述字符串/枚举/任何内容放在 Base 中并初始化它的派生类。然后可以初始化 templ。基于该描述的工厂 obj 中的类。我认为如果我可以推断出指针类型,我可以避免这种情况。正如 Space_C0wb0y 所说,这是不可能的。感谢您的宝贵时间,请接受我以非常糟糕的方式提出问题的道歉。欢呼

标签: c++ templates pointers types


【解决方案1】:

function 抽象为Base 是否更有意义,这样您就不需要知道它是哪个派生类?

【讨论】:

  • 就是这样。我不能。由于性能问题,我想避免在 Base 的子类中使用虚函数
  • @dodol:您在这里所做的称为过早优化。请使用虚函数。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    在您的情况下真的需要模板类吗?在给定的示例中,您可以将方法“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;
    }
    

    【讨论】:

    • 在他的情况下,他甚至不需要 C++。一些带有结构体和函数指针的 C 代码会做得很好。
    猜你喜欢
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    相关资源
    最近更新 更多