简体   繁体   English

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

[英]Programmatically getting the name of a derived class

I am attempting to do something like:我正在尝试做类似的事情:

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

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

Derived d;
MoreDerived m;

Problem is, I always get Base printed to the screen, when I need to see Derived and MoreDerived .问题是,当我需要查看DerivedMoreDerived时,我总是将Base打印到屏幕上。 Is there a way to get typeid to work this way with derived classes?有没有办法让 typeid 以这种方式与派生类一起工作? Or is there another approach besides typeid ?或者除了typeid还有其他方法吗?

Note: I am adding functionality to an already coded suite, so I don't want to have to add a virtual method to the base class where the derived classes return this value themselves.注意:我正在向已编码的套件添加功能,因此我不想在派生类自己返回此值的基础 class 中添加虚拟方法。 Also, not worried about runtime overhead, this will be part of a debug compile switch.此外,不用担心运行时开销,这将是调试编译开关的一部分。

In the constructor Base(), the object is still a "Base" instance.在构造函数 Base() 中,object 仍然是一个“Base”实例。 It will become a Derived instance after the Base() constructor.它将在 Base() 构造函数之后成为 Derived 实例。 Try to do it after the construction and it will work.尝试在施工进行,它会起作用。

See for example:参见例如:

You can't do that from within a constructor (or destructor) - neither with typeid nor with a virtual method.您不能在构造函数(或析构函数)中执行此操作——无论是使用typeid还是使用虚拟方法。 The reason is while you're in a constructor the vtable pointer is set to the base class being constructed, so the object is of base class and no amount of polymorphism will help at that point.原因是当您在构造函数中时,vtable 指针设置为正在构造的基础 class,因此 object 是基础 class 并且在该点上没有任何多态性。

You have to execute that code after the most derived class has been constructed .您必须在构造最派生的 class 之后执行该代码。 One option would be to use a factory function:一种选择是使用工厂 function:

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

Another option is to provide a virtual toName() function另一种选择是提供一个虚拟 toName() function

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

This might get tedious since you need to manually create each toName function.这可能会变得乏味,因为您需要手动创建每个 toName function。 But the advantage it gives you is to provide your own custom name.但它给您的好处是提供您自己的自定义名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM