首页 > 解决方案 > typeid.name 在派生类类型之前返回一个数字

问题描述

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

class Question{
};

class QSingleChoice{
};

class QMultipleChoice{
};

etc.

我有一个vector<Question*>存储多种问题类型的。在 GUI 中,我需要知道我必须显示什么类型的问题,所以我使用string questionType = typeid(*question).name()的是“QSingleChoice”、“QMultipleChoice”等而不是“13QSingleChoice”、“5QText”、“9QOrdering”等。什么是那些数字?我是否可以假设它们总是相同的,或者当我在另一台计算机上运行程序时,typeid 可能会返回类似“19QSingleChoice”或完全不同的东西,例如“ASDQSingleChoice”?

标签: c++polymorphismtypeid

解决方案


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

如果需要,最好自己引入这些功能,也许以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 很大程度上在问题之外,那么使用访问者模式可能更合适。


推荐阅读