是否有可能打印迭代器指向的类的名称?

时间:2013-12-30 16:52:05

标签: c++ oop

假设我有一个按照以下层次结构运行的程序: DIAGRAM

我有Human *的链接列表容器,我正在使用std::list<Human *>::iterator human进行迭代。以下迭代器可以指向MenWomenFlying Men。是否有可能,像typeid(*human).name()之类的东西会返回指向对象所属的类的名称?当我使用typeid.name()时,我得到class Human *

4 个答案:

答案 0 :(得分:1)

您可以在对象typeid本身使用**human,而不是指针,它始终具有类型Human*,无论它指向何处。只要Human是多态的(也就是说,它声明至少一个虚函数),它就会为你提供对象动态类型的类型信息。

请注意,名称不一定是人类可读的,甚至是唯一的;如果指针指向类型3Man,我的编译器会给出受损的名称Man,而其他编译器可能会给出其他的恶意。如果你想要一个很好的人类可读名称,你必须声明自己的虚拟成员函数来返回一个。

答案 1 :(得分:1)

在运行时根据类型检查选择执行路径错误,因为它将知识放在不应该的位置,并且因为所有检查都必须使用新的扩展,因此更难添加新类型输入id。

相反,定义一个接口,允许所有需要它的类型创建自己的版本。这是一个可编辑的例子,你可以复制和玩。请注意,添加应序列化的新类型不会更改现有类中的任何代码,也不需要新的测试。并且,作为奖励,所有内容都在编译时进行类型检查,因此无法使用错误类型的对象添加调用。

#include <iostream>
#include <list>

#include <boost/foreach.hpp>

class Output {
public:
  // Whatever operations needed
  int Write(int value) {
    std::cout << value << std::endl;

    return 0;
  }
};

class Human {
public:
  virtual ~Human() {}

  virtual int Serialize(Output& output) = 0;
};

class Men : public Human {
public:
  int Serialize(Output& output) {
    return output.Write(17);
  }
};

class Women : public Human {
public:
  int Serialize(Output& output) {
    return output.Write(42);
  }
};

int main(int argc, char* argv[]) {
  Output output;

  Men men1;
  Men men2;
  Women women1;
  Women women2;

  std::list<Human*> toSerialize;

  toSerialize.push_back(&men1);
  toSerialize.push_back(&women1);
  toSerialize.push_back(&men2);
  toSerialize.push_back(&women1);

  BOOST_FOREACH(Human* human, toSerialize) {
    human->Serialize(output);
  }

  return 0;
}

答案 2 :(得分:0)

没有。 Typeinfo是您将获得的最佳反映。如果你真的需要这个,请创建一个返回正确名称的虚拟成员函数。

答案 3 :(得分:0)

是的,但您的课程必须具有虚拟功能。最好的地方是使用虚拟析构函数,因为它很可能需要尽早而不是迟到。

另请注意,typeid未定义为您提供可读名称。如果它与你目前的目标编译器有关,那很好。如果没有,您可能需要添加像const std::string &className() const这样的虚拟函数来获得您想要的内容。