在C ++中获取类名有哪些好方法?

问题描述 投票:1回答:2

我不是在谈论typeid,我只是在寻找将单个对象(例如我的情况下的std :: string)绑定到某个类的对象并使其getter多态的东西的通用方法。我不能真正给出一个正确的定义,所以我认为这就像获得一个类名的问题,但你自己设置在某个地方,唯一的问题是你在哪里设置它,你如何返回它。

我只是举几个例子来做我想做的事,但并不像我想要的那样高效。

  • virtual string GetClassName() const { return string("MyClass"); } - 每次调用时都会花费额外的时间来构建和复制字符串
  • const string& GetClassName() const { return class_name_; }其中class_name_是在构造函数中设置的受保护类字段 - 相同的字符串存储在每个对象中,因此它不具有内存效率

我正在考虑将const引用返回给静态对象,但我无法真正找到使其具有多态性的方法。

有任何想法吗?

c++ types polymorphism typing classname
2个回答
1
投票

当你可以用正确的轮胎延长它时,你不需要重新发明轮子。

C ++标准为您提供适用于所有情况的typeid(),包括内置类型,自定义类,多态类,多重继承,虚拟继承等等。

现在你可能不喜欢typeid()使用的名称,这些名称是特定于实现的。或者,您可能希望使用自己的类型管理扩展来扩展可用信息。在这种情况下,Bjarne Stroustrup在“C ++的设计和演化”中提出了一个非常简单有效的解决方案。

typeid()返回对const std::type_info的引用。现在,您可以在unordered_map中使用此对象的地址,将类型映射到您自己的可提供所需名称的自定义信息。

此解决方案的优点:使用强大的内置功能,基于每个类的一个额外对象(可能是静态的),获得名称的开销非常低。您需要做的就是考虑如何最好地填充地图。

这里有一个小而快速的概念证明(当然必须改进):

// Basic principle of the idea
map<const type_info*, string> mytypes;  

template <class T>
const string& mytype(T &&x) {
    return mytypes[&typeid(x)];
}

// Some test types 
struct A { virtual int test() {} };
struct B : A {}; 

int main() {
    // To be improved:  initialization of the type info extension 
    mytypes[&typeid(int)]="Plain C++ integer";
    mytypes[&typeid(A)]="Structure A";
    mytypes[&typeid(B)]="Structure B";

    // demo, including polymorphic type     
    int a; 
    A * p = new B;
    cout << typeid(int).name() <<endl; 
    cout << mytype(a) <<endl; 
    cout << mytype(*p) <<endl; 
    return 0;
}

Online demo


0
投票

我认为你想要的是一些带有NamedClass的基础virtual std::string_view getName() const,它返回派生类的名称。所以你想要像typeid(object).name()这样的东西,但没有名字错误。

NamedClass派生的每个类都应该覆盖getName并返回类名。

class NamedClass {
public:
  virtual std::string_view getName() const = 0;
};

class Derived final : public NamedClass {
public:
  std::string_view getName() const override {
    return "Derived";
  }
};

如果你像我一样讨厌这种重复,你可以使用一个宏。

#define GET_NAME(NAME) \
  std::string_view getName() const override { return #NAME; }

class Derived final : public NamedClass {
public:
  GET_NAME(Derived)
};

我强烈建议使用std::string_view而不是const std::string &,如果你想做的就是“查看”字符串。

© www.soinside.com 2019 - 2024. All rights reserved.