web-dev-qa-db-fra.com

Qu'est-ce que qobject_cast?

Quelqu'un pourrait-il expliquer en termes aussi simples que possible (ou aussi simple que vous le souhaitez) ce que qobject_cast est, ce qu'il fait et pourquoi nous devrions convertir un type de classe en un autre?

Par exemple, j'obtiens le transtypage dans le sens de convertir un int en char ou QString peut-être pour utiliser QMessageBox, mais pourquoi le cast dans différentes classes?

10
Michael Thomas

Avant de commencer à apprendre ce que qobject_cast est, vous auriez besoin de savoir ce que C++ dynamic_cast est. La conversion dynamique concerne polymorphisme .

Le cast dynamique de C++ utilise RTTI (Run Time Type Information) pour caster un objet. Mais qobject_cast le fait sans RTTI.

Qu'est-ce que la distribution dynamique?

Par exemple, supposons que nous ayons une fonction d'usine automobile. Comme ça:

Car* make_car(string brand){
    if(brand == "BMW"){
        return new BmwCar;
    }
    if(brand == "Audi"){
        return new AudiCar;
    }
    return nullptr;
}

Notez que les classes BmwCar et AudiCar héritent de la classe Car. En utilisant cette fonction, nous pouvons fabriquer différentes voitures en utilisant une seule fonction. Par exemple:

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

Sans pour autant dynamic_cast vous ne pourrez pas déterminer si car est un BmwCar ou un AudiCar.

Quelle est la différence entre dynamic_cast et qobject_cast?

  • qobject_cast ne peut être utilisé qu'avec QObject classes dérivées ayant Q_OBJECT macro.

  • qobject_cast n'utilise pas RTTI.

18
frogatto

qobject_cast est la même chose que dynamic_cast , mais ne fonctionne que pour les enfants de QObject. Il ne nécessite pas RTTI et il fonctionne beaucoup plus rapidement, car il n'est pas possible d'utiliser QObject dans héritage multiple .

N'hésitez pas à faire votre propre recherche et à lire quelques choses de base sur OOP et C++. Surtout sur le polymorphisme. Et n'hésitez pas à lire la documentation de Qt, elle contient beaucoup de comprendre des exemples.

Une utilisation de ressentiment de qobject_cast obtient un pointeur vers une classe à l'intérieur d'un 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!" );
}
16
Dmitry Sazonov