如何获取班级名称?

Posted

技术标签:

【中文标题】如何获取班级名称?【英文标题】:How to get class name? 【发布时间】:2011-05-26 20:24:17 【问题描述】:

如果我定义了一个类:

class Blah ;

我该怎么做:

std::string const className = /* What do I need to do here? */;
assert( className == "Blah" );

我认为 typeid().name() 不是一个好主意,因为它是 compiler implementation 特定的。 C++ 标准或 Boost 是否提供了什么?

注意:如果类是从 Qt 的 QObject 继承的,我可以很容易地使用QMetaObject::className() 来获取类名。

【问题讨论】:

【参考方案1】:

像这样:

class Blah  static std::string const className()  return "Blah"; ;

std::string const name = Blah::className();
assert(name == "Blah");

或者这个:

class Blah ;

template < typename T > struct name;
template < > struct name<Blah>  static std::string value()  return "Blah"; ;

std::string const classname = name<Blah>::value();
assert(classname == "Blah");

鸽友:

#define DECLARE_NAMED_CLASS( Name ) \
struct Name;\
template < > struct name<Name>  static std::string value()  return #Name; ;\
struct Name

DECLARE_NAMED_CLASS(Blah) ;
std::string const className = name<Blah>::value();
...

或者这个:

class Blah : QObject  Q_OBJECT ;

或者这个:... 或者这样:...

【讨论】:

另一种解决方案是 typeid () + demangle。否则,你怎么能处理命名空间等? 第一种情况是唯一严重的。它易读、易于维护和使用。第二个使一个简单的问题过于复杂。也许您更愿意使用 REST API 来调用 Web 服务?第三个被认为是坏习惯。当谈到好的设计时,预处理器是最糟糕的,也是你应该使用的最后一件事。我能想到的唯一几个合理的预处理器用例是pragma once。【参考方案2】:

通过查看一个类的名称来测试一个类对我来说听起来非常像 Java 风格的方法,而在 C++ 中,您应该警惕尝试应用相同的模式!更好的方法是使用 boost::type_traits 之类的名称,并且可能是 is_same,并带有真实的类名。

【讨论】:

【参考方案3】:

我认为dynamic_cast 可能是您正在寻找的。 它不会给你类的名称,但它会以你希望断言失败的方式失败,除了Blah 的子类不会被捕获。

【讨论】:

【参考方案4】:

我认为没有任何非编译器特定的解决方案可以解决此类问题,在类声明中不涉及大量宏(实际上,如果我正确理解 QT 文档,您使用 objectName 获得的字符串实际上已分配“手动”,我认为是由moc 创建的代码)。

另一方面,一般来说,要检查一个对象的类是否是你不想要的,你不应该做一个字符串比较,而是做一个 typeid 比较。

assert(typeid(YourObject)==typeid(Blah));

但也许你应该更好地解释你想要达到的目标。

【讨论】:

【参考方案5】:

QObject->metaObject() 方法对 Qt 有效,除了不从 QObject 继承的基于 QGraphicsItem 的类...

【讨论】:

【参考方案6】:

我认为 typeid().name() 不是一个好主意,因为它是编译器 具体实现。

是的,标准不要求从实现中使用任何特定的命名,因此即使对于同一个编译器,它也可能会发生变化。

C++ 标准或 Boost 是否提供了什么?

没有标准工具可以以某种规范形式返回类名。

【讨论】:

以上是关于如何获取班级名称?的主要内容,如果未能解决你的问题,请参考以下文章

班级云相册code获取失败怎么解决

我如何从一个班级获取信息到另一个班级

使用反射获取 T 的类型名称

如何使用流从对象列表中获取地图? [复制]

如何将来自一个 JSON 请求的数据用于第二个 JSON 请求?

如何获取listView位置值并通过intent传递给另一个类