12

如果我定义了一个类:

class Blah {};

我怎样才能:

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

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

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

4

6 回答 6

10

像这样:

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

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

于 2010-12-16T22:53:35.770 回答
3

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

于 2010-12-16T22:53:49.943 回答
1

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

另一方面,通常要检查对象的类是否是您不希望的对象,您不应该进行字符串比较,而是进行 typeid 比较。

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

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

于 2010-12-16T22:44:42.490 回答
1

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

于 2010-12-16T22:57:16.637 回答
1

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

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

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

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

于 2010-12-16T23:16:13.297 回答
1

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

于 2011-11-10T14:25:05.847 回答