Domanda

Ho appena trovato il seguente codice in Qt e io sono un po 'confuso quello che sta succedendo qui.

Tanto più che a ciò che reinterpret_cast<T>(0) fa?

template <class T>
inline T qobject_cast(const QObject *object)
{
    // this will cause a compilation error if T is not const
    register T ptr = static_cast<T>(object);
    Q_UNUSED(ptr);

#if !defined(QT_NO_MEMBER_TEMPLATES) && !defined(QT_NO_QOBJECT_CHECK)
    reinterpret_cast<T>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(const_cast<QObject *>(object)));
#endif
    return static_cast<T>(const_cast<QObject *>(reinterpret_cast<T>(0)->staticMetaObject.cast(const_cast<QObject *>(object))));
}

Chiunque si preoccupa di spiegare?

È stato utile?

Soluzione

Questo è un po 'complicato ...

Ricordate che qobject_cast<T>(obj) è un modo per lanciare in modo dinamico un QObject a il tipo di destinazione T che deriva anche da QObject. Ora, per questo al lavoro, il Q_OBJECT macro dovrebbe essere inclusa nella definizione della classe di T.

A quanto pare, la chiamata qt_check_for_QOBJECT_macro è per controllare che la classe non contiene effettivamente la macro Q_OBJECT. Quando la macro viene espansa, contiene le seguenti definizioni:

template <typename T> inline void qt_check_for_QOBJECT_macro(const T &_q_argument) const 
   { int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i; }

template <typename T1, typename T2>
inline int qYouForgotTheQ_OBJECT_Macro(T, T) { return 0; }

Quindi, se si dispone di un oggetto di tipo x T ed un y oggetto di tipo U, il x->qt_check_for_QOBJECT_macro(y) chiamata chiama la funzione qYouForgotTheQ_OBJECT_Macro con i parametri di tipi T* e U*. Poiché la funzione viene templato con un parametro singolo tipo, i tipi T e U devono essere uguali.

Ora, se si chiama x->qt_check_for_QOBJECT_macro(x) allora si dovrebbe aspettare i tipi di essere lo stesso e per la compilazione a banalmente avere successo. Tuttavia, ricorda che this ha lo stesso tipo come la classe il metodo è stato definito in. Quindi, se x è di una classe che è stato derivato dal T ma non contiene la propria definizione di qt_check_for_QOBJECT_macro, la chiamata avrà esito negativo.

Quindi abbiamo un modo per verificare se il tipo di destinazione T contiene il meccanismo corretto per il cast dinamico, ma non abbiamo un oggetto di tipo T per chiamare questo metodo su ancora. Questo è ciò che la reinterpret_cast<T>(0) è per. Non abbiamo bisogno di un oggetto reale come this, dal momento che il compilatore ha bisogno solo i tipi di oggetti per il controllo per avere successo. Invece, noi chiamiamo un metodo su un puntatore nullo di tipo T.

Non credo che ciò sia consentito dal C ++ standard, ma opera da this non viene effettivamente utilizzato all'interno del metodo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top