now*_*wox 3 c++ polymorphism rtti typeid
在下面的例子中,我不希望 stdout : Base Foo Bar,但我得到P4Base P4Base P4Base:
#include <iostream>
#include <typeinfo>
#include <vector>
#include <memory>
class Base {};
class Foo : public Base {};
class Bar : public Base {};
using Collection = std::vector<std::unique_ptr<Base> >;
int main() {
Collection collection;
collection.push_back(std::make_unique<Base>());
collection.push_back(std::make_unique<Foo>());
collection.push_back(std::make_unique<Bar>());
for (auto &u:collection)
std::cout << typeid(u.get()).name() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
有没有办法正确识别我的集合中有哪种实例?
编辑
在eerorika的建议下的一个工作示例
struct Base {virtual ~Base() = default;};
struct Foo : public Base {};
struct Bar : public Base {};
using Collection = std::vector<std::unique_ptr<Base> >;
int main() {
Collection collection;
collection.push_back(std::make_unique<Base>());
collection.push_back(std::make_unique<Foo>());
collection.push_back(std::make_unique<Bar>());
for (auto &u:collection)
std::cout << typeid(*u).name() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
Typeinfo 如何在多态集合中获取类的名称/ID?
typeid提供动态类型,类必须是多态的。你的类不是多态的,所以你会得到静态类型。typeid指针为您提供指针类型的类型信息,而不是指向对象的类型。要修复第一点和第三点,请为基础提供一个虚拟析构函数。修复第二个:
typeid(*u).name()
Run Code Online (Sandbox Code Playgroud)
最后,您对可读类名的期望是错误的。std::type_info::name不能保证给你你为班级写的名字。结果是实现定义的,实际上您通常会得到类型的重整名称。没有获得可读名称的标准方法,但有实现定义的方法来对名称进行解构。