如何获取班级名称?
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 是否提供了什么?
没有标准工具可以以某种规范形式返回类名。
【讨论】:
以上是关于如何获取班级名称?的主要内容,如果未能解决你的问题,请参考以下文章