Reputation: 503
Could someone explain in as simple terms as possible (or as simple as you would like) what qobject_cast
is, what it does and why we would need to cast one class type to another?
Like, I get typecasting in the sense of casting an int
as a char
or QString
maybe to use QMessageBox
, but why cast into different classes?
Upvotes: 35
Views: 49053
Reputation: 9014
qobject_cast
is same thing as dynamic_cast
, but works only for children of QObject
. It doesn't require RTTI and it works much faster, because it is not possible to use QObject
in multiple inheritance.
Don't hesitate to do self-research and to read some basic things about OOP and C++. Especially about polymorphism. And don't hestiate to read Qt documentation, it contains a lot of easy-to-understand examples.
A common use case of qobject_cast
is getting a pointer to a class inside a slot:
QObject::connect( btn, &QPushButton::clicked, this, &MyClass::onClicked );
void MyClass::onClicked()
{
// How to get pointer to a button:
QObject *p = sender();
// It's QObject. Now we need to cast it to button:
QPushButton *btn = qobject_cast<QPushButon *>( p );
Q_ASSERT( btn != nullptr ); // Check that a cast was successfull
// Now we can use a QObject as a button:
btn->setText( "We just clicked on a button!" );
}
Upvotes: 32
Reputation: 29285
Before you start learning what qobject_cast
is, you would need to know what C++'s dynamic_cast
is. Dynamic cast is all about polymorphism.
C++'s dynamic cast uses RTTI (Run Time Type Information) to cast an object. But qobject_cast
does this without RTTI.
For example suppose we've got a car factory function. Like this:
Car* make_car(string brand){
if(brand == "BMW"){
return new BmwCar;
}
if(brand == "Audi"){
return new AudiCar;
}
return nullptr;
}
Note that BmwCar
and AudiCar
classes inherit Car
class. Using this function we can make different cars only using one function. For example:
string brand;
cin >> brand;
Car *car = make_car(brand);
BmwCar *bmw = dynamic_cast<BmwCar*>(car);
if (bmw != nullptr) {
cout << "You've got a BMW!";
}
AudiCar *audi = dynamic_cast<AudiCar*>(car);
if (audi != nullptr) {
cout << "You've got a Audi!";
}
Without dynamic_cast
you won't be able to determine if car
is a BmwCar
or an AudiCar
.
dynamic_cast
and qobject_cast
?qobject_cast
can only be used with QObject
derived classes having Q_OBJECT
macro.
qobject_cast
doesn't use RTTI.
Upvotes: 53