以编程方式获取派生类的名称

时间:2011-07-19 12:27:06

标签: c++ typeid

我正在尝试做类似的事情:

class Base {
public:
   Base() {
      cout << typeid(*this).name() << endl;
   }
   ...
};

class Derived : public Base { ... }
class MoreDerived : public Derived { ... }

Derived d;
MoreDerived m;

问题是,当我需要BaseDerived时,我总是会在屏幕上显示MoreDerived。有没有办法让typeid以派生类的方式工作?或者除了typeid之外还有另一种方法吗?

注意:我正在为已编码的套件添加功能,所以我不想在基类中添加虚方法,派生类本身会返回此值。此外,不担心运行时开销,这将是调试编译开关的一部分。

3 个答案:

答案 0 :(得分:14)

在构造函数Base()中,该对象仍然是“Base”实例。它将成为Base()构造函数之后的Derived实例。 构建之后尝试,它会起作用。

参见例如:

Avoiding virtual methods in constructor

http://www.artima.com/cppsource/nevercall.html

答案 1 :(得分:10)

您无法在构造函数(或析构函数)中执行此操作 - 既不使用typeid也不使用虚方法。原因是当你在构造函数中时,vtable指针被设置为正在构造的基类,因此该对象属于基类,并且在这一点上没有多少多态将有所帮助。

在构造了最多派生类之后,您必须执行该代码 。一种选择是使用工厂功能:

template<class T>
T* CreateInstance()
{
    T* object = new T();
    cout << typeid(*object).name() << endl;
    return object;
}

答案 2 :(得分:0)

另一种选择是提供虚拟的toName()函数

struct Object{
  virtual std::string toName() const = 0;
}
struct Base: Object{
  std::string toName()const{ return "Base"; }
}
struct Derived: Base, Object{
  std::string toName()const{ return "Derived"; }

这可能会变得乏味,因为您需要手动创建每个toName函数。但它给你的好处是提供你自己的自定义名称。