在C 中获得班级名称的一些好技术是什么?

What are some good techniques for getting class name in C++?

本文关键字:技术 是什么      更新时间:2023-10-16

我不是在谈论typeid,我只是在寻找绑定单个对象(例如,在我的情况下像std :: string)的常规方法与某些类的对象并进行制作它的多态性或其他东西。我真的不能给出适当的定义,所以我认为这就像获得班级名称的问题一样,但是您自己将其设置在某个地方,唯一的问题是您将其设置在哪里以及如何返回。

我只会给一些我想要的例子,但并不像我想要的那样效率。

  • virtual string GetClassName() const { return string("MyClass"); }-每次称为
  • const string& GetClassName() const { return class_name_; }其中 class_name_是构造函数中设置的受保护的类字段 - 同一字符串存储在每个对象中,因此它不是内存效率

我正在考虑返回const引用静态对象之类的东西,但我真的找不到使其成为多态性的方法。

有什么想法?

当您可以用正确的轮胎扩展时,您不需要重新发明车轮。

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;
}

在线演示

我认为您想要的是一些基本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 &,如果您要做的就是"查看"字符串。