例子:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | #include <QCoreApplication>#include <QDebug>
 #include <typeinfo>
 class Base : public QObject
 {
 Q_OBJECT
 public:
 explicit Base(QObject *parent = 0) {}
 };
 class Foo : public Base
 {
 Q_OBJECT
 public:
 Foo(QObject *parent = 0) : Base(parent) {}
 };
 int main(int argc, char *argv[])
 {
 QCoreApplication a(argc, argv);
 Base *obj = new Foo();
 auto b = qobject_cast<Base *>(obj);
 qDebug() << (b != nullptr);
 qDebug() << obj->metaObject()->className();
 qDebug() << typeid(obj).name();
 return a.exec();
 }
 #include "main.moc"
 
 | 
输出结果:
不难看出,当需要明确根据类型进行不同逻辑时,可能会产生意想不到的问题。
在我们的项目中,有一个表单类TUiLoader。有两个控件类,分别是TLineEdit和TDateTimeEdit。
大概长这样:
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | class TLineEdit {};class TDateTimeEdit : public TLineEdit {};
 class TUiLoader : public QFrame {
 Q_OBJECT
 public:
 void doSomething(QObject *obj);
 private:
 QList<QObject *> objs;
 }
 
 | 
当我们在doSomething函数中要根据不同的类型进行不同逻辑时,例如:
| 12
 3
 4
 5
 6
 7
 
 | void TUiLoader::doSomething(QObject *obj) {if (qobject_cast<TLineEdit *>(obj)) {
 
 } else if (qobject_cast<TDateTimeEdit *>(obj)) {
 
 }
 }
 
 | 
危险!TDateTimeEdit当然可以转换成TLineEdit, 因此执行了TLineEdit的逻辑,这并不是我想要的。
如何解决?
可以在doSomething中调换判断的顺序,或者用元对象的className进行RTTI。