Michael Thomas
Michael Thomas

Reputation: 503

What is qobject_cast?

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

Answers (2)

Dmitry Sazonov
Dmitry Sazonov

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

frogatto
frogatto

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.

What is dynamic cast?

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.

What is different between 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

Related Questions