typeid.name在派生类类型之前返回一个数字

时间:2018-05-26 15:16:24

标签: c++ polymorphism typeid

我有这些类:(类问题是抽象的,其他的是派生的)

class Question{
};

class QSingleChoice{
};

class QMultipleChoice{
};

etc.

我有vector<Question*>存储多种问题类型。在GUI中我需要知道我要显示什么类型的问题,所以我使用string questionType = typeid(*question).name()而不是&#34; QSingleChoice&#34;,&#34; QMultipleChoice&#34;它返回&#34; 13QSingleChoice&#34;,&#34; 5QText&#34;,&#34; 9QOrdering&#34;那些数字是什么?我可以假设它们总是相同的,或者当我在不同的计算机上运行程序时,typeid会返回类似于&#34; 19QSingleChoice&#34;或类似于&#34; ASDQSingleChoice&#34;?

1 个答案:

答案 0 :(得分:4)

std::type_info::name返回的名称是实现定义的,这意味着完全取决于每个编译器决定它如何表示类型的名称。换句话说,这不是你可以依赖的东西。它对于调试很有用,并且可以在程序的同一次运行中用于某些比较,但我不认为它可用于更多:你必须检查编译器的文档以确定它是否提供了你需要的guarentees。

如果您需要,可能会以virtual const std::string& classId() const;的形式自行引入此类功能通常要好得多。

可以这样实现:

class Question {
public:
  virtual const std::string& getClassId() const = 0;
};

class QSingleChoice : public Question {
public:
  const std::string& getClassId() const override
  {
    static const std::string name{"SingleChoice"};
    return name;
  }
};


class QMultipleChoice : public Question {
public:
  const std::string& getClassId() const override
  {
    static const std::string name{"MultipleChoice"};
    return name;
  }
};

或者,您可以创建并返回枚举而不是字符串名称。

但是,首先要确保您确实需要它。通常,检查和识别隐藏在抽象界面后面的特定类型的需要表明设计不良。如果GUI是程序的组成部分,那么Question可能只提供virtual void display() const;等虚拟功能。或者,如果GUI主要在问题外部,那么使用visitor pattern可能更合适。