C++ 使用RTTI从实现接口c+;的对象获取类名+;

C++ 使用RTTI从实现接口c+;的对象获取类名+;,c++,reflection,unique-ptr,C++,Reflection,Unique Ptr,我在Animal命名空间中有一个类AnimalInterface: namespace Animal { class AnimalInterface { public: AnimalInterface() = default; virtual ~AnimalInterface() = default; virtual std::string makeSound() = 0; }; } 假设我有两个类从这个接口实现

我在Animal命名空间中有一个类AnimalInterface:

namespace Animal
{
    class AnimalInterface
    {
    public:
        AnimalInterface() = default;
        virtual ~AnimalInterface() = default;

        virtual std::string makeSound() = 0;
    };
}
假设我有两个类从这个接口实现

class Dog : public AnimalInterface
{
public:
    Dog() = default;
    ~Dog() = default;

    std::string makeSound()
    {
        return "Bark";
    }
};

class Cat : public AnimalInterface
{
public:
    Cat() = default;
    ~Cat() = default;

    std::string makeSound()
    {
        return "Meow";
    }
};
现在我有了一个类,从中调用这些函数。我希望能够使用运行时类型信息从对象中获取动物的类名

void AnimalSounds
{
    list<unique_ptr<AnimalInterface>> animals;
    animals.push_back(make_unique<Dog>());
    animals.push_back(make_unique<Cat>());

    for (const auto& animal : animals)
    {

        cout << typeid(animal).name() << " makes sound: " << animal->makeSound() << endl;
    }
}
相反,我得到了以下结果

class std::unique_ptr<class Animal::AnimalInterface,struct std::default_delete<class Animal::AnimalInterface> > makes sound: Bark
class std::unique_ptr<class Animal::AnimalInterface,struct std::default_delete<class Animal::AnimalInterface> > makes sound: Meow
class std::unique_ptr发出声音:树皮
class std::unique_ptr发出声音:喵喵

我该如何解决这个问题?谢谢

我认为您遇到的意外问题是,您的
动物
列表包含
动物
唯一的ptr
。因此,当您迭代该列表时,循环中的每个
animal
都是一个
唯一的\u ptr
,这是一个带有默认参数的模板。要至少解决该问题,请在使用
typeid
之前取消对指针的引用:

for (const auto& animal : animals)
{
  cout << typeid(*animal).name() << " makes sound: " << animal->makeSound() << endl;
}
for(常数自动和动物:动物)
{

cout您需要取消对指针的引用。这样您可以从指针指向的对象而不是指针本身获取RTTI信息:

const auto&animal\u ref=*animal;
cout1.
animal
是对
animals
中某些元素的引用。
animals
包含什么?它包含
unique\ptr:

不提供任何保证;特别是,返回的字符串对于几种类型可能是相同的,并且在同一程序的调用之间会发生变化


我只能想到一种稳健的标准兼容的方法来实现你想要的:另一个虚拟的函数,它返回动物种类。或者一些特定于编译器的扩展,但是标准C++目前没有任何真实的反映。< / P>我想用反射法从动物中获取动物的类名。在这个时候,C++中没有反射。这看起来像是由代码> Type ID > /Cord>返回的字符串。定义了什么类型的代码<代码>动物< /代码>。它是真的<代码>狗>代码>还是<代码> CAT<代码>?你不能依赖于代码> Type ID(…)。
无论如何,它的输出既不是类名,也不是一致的(即使在一个程序和同一个程序的执行之间也是如此)。那么--
std::unordered\u map
或者如果动物可以有重复的名称
std::unordered\u multimap
for (const auto& animal : animals)
{
  cout << typeid(*animal).name() << " makes sound: " << animal->makeSound() << endl;
}
3Dog makes sound: Bark
3Cat makes sound: Meow
Dog makes sound: Bark
Cat makes sound: Meow