我正在尝试做类似的事情:
class Base {
public:
Base() {
cout << typeid(*this).name() << endl;
}
...
};
class Derived : public Base { ... }
class MoreDerived : public Derived { ... }
Derived d;
MoreDerived m;
问题是,当我需要Base
和Derived
时,我总是会在屏幕上显示MoreDerived
。有没有办法让typeid以派生类的方式工作?或者除了typeid
之外还有另一种方法吗?
注意:我正在为已编码的套件添加功能,所以我不想在基类中添加虚方法,派生类本身会返回此值。此外,不担心运行时开销,这将是调试编译开关的一部分。
答案 0 :(得分:14)
在构造函数Base()中,该对象仍然是“Base”实例。它将成为Base()构造函数之后的Derived实例。 构建之后尝试,它会起作用。
参见例如:
答案 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函数。但它给你的好处是提供你自己的自定义名称。