C++ 使用RTTI从实现接口c+;的对象获取类名+;
我在Animal命名空间中有一个类AnimalInterface: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; }; } 假设我有两个类从这个接口实现
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