[ fromfile: qtrtti.xml id: qtrtti ]
RTTI, or Run Time Type Identification, as its name suggests, is a system for determining at runtime the actual type of an object, to which you may have only a base class pointer.
In addition to C++'s RTTI operators, dynamic_cast
and typeid
(Section 19.10), Qt provides two mechanisms for runtime
type identification.
qobject_cast
QObject::inherits()
qobject_cast
is an ANSI-style typecast operator (Section 19.8).
ANSI typecasts look a lot like template functions:
DestType* qobject_cast<DestType*> ( QObject * qoptr )
A typecast operator converts an expression from one type
to another, following certain rules and restrictions imposed by the types and the language.
Like other cast operators, qobject_cast
takes the destination type as a template
parameter.
It returns a DestType
pointer to the same object.
If at runtime, the actual pointer type cannot be converted to DestType*
, the
conversion fails and the value returned is NULL
.
As the signature suggests, qobject_cast
is type-restricted to arguments of type ObjectType*, where ObjectType is derived from QObject and the class was fully
processed by moc
(which requires it to have the Q_OBJECT
macro in its class definition).
qobject_cast
is actually a downcast operator, similar to dynamic_cast
.
It permits you to cast pointers and references from a more general to a more specific type.
You may find that qobject_cast
works 5 to 10 times faster than dynamic_cast
, depending on what compiler you use.
In situations where you have base class pointers to derived class objects, downcasting makes it possible to call derived class methods that do not exist in the base class interface.
A common place to find qobject_cast
is in concrete implementations of QAbstractItemDelegate,
such as Example 12.1.
Most of the virtual functions take QWidget* as an argument, so you can do
dynamic type checking to determine which kind of widget it is.
Example 12.1. src/modelview/playlists/stardelegate.cpp
[ . . . . ] void StarDelegate:: setEditorData(QWidget* editor, const QModelIndex& index) const { QVariant val = index.data(Qt::EditRole); StarEditor* starEditor = qobject_cast<StarEditor*>(editor); if (starEditor != 0) { StarRating sr = qVariantValue<StarRating>(val); starEditor->setStarRating(sr); return; } TimeDisplay* timeDisplay = qobject_cast<TimeDisplay*>(editor); if (timeDisplay != 0) { QTime t = val.toTime(); timeDisplay->setTime(t); return; } SUPER::setEditorData(editor, index); return; }
Dynamic type checking. |
|
Extract user type value from QVariant. |
|
Dynamic type checking. |
|
Let base class handle other types. |
Note | |
---|---|
The implementation of |
Multiple Inheritance and qobject_cast | |
---|---|
For |
QObject also offers a deprecated,
Java-style typechecking function, inherits()
.
Unlike qobject_cast
, inherits()
accepts a char*
type name instead of a type expression.
This operation is slower than qobject_cast
because it requires an extra hashtable
lookup, but it can be useful if you need input-driven type checking.
Example 12.2 shows
some client-code that uses inherits()
.
Example 12.2. src/qtrtti/qtrtti.cpp
[ . . . . ] // QWidget* w = &s; if (w->inherits("QAbstractSlider")) cout << "Yes, it is "; else cout << "No, it is not"; cout << "a QAbstractSlider" << endl; if (w->inherits("QListView")) cout << "Yes, it is "; else cout << "No, it is not "; cout << "a QListView" << endl; return 0; }
Generated: 2012-03-02 | © 2012 Alan Ezust and Paul Ezust. |