質問

QTで次のコードを見つけたばかりで、ここで何が起こっているのか少し混乱しています。

特に何について reinterpret_cast<T>(0) やりますか?

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))));
}

誰かが説明したいですか?

役に立ちましたか?

解決

これは少し複雑です...

それを覚えておいてください qobject_cast<T>(obj) 動的にキャストする方法です QObject ターゲットタイプに T それも派生しています QObject. 。さて、これが機能するためには、マクロです Q_OBJECT クラスの定義に含める必要があります T.

どうやら、 qt_check_for_QOBJECT_macro 呼び出しは、クラスにq_objectマクロが実際に含まれていることを確認するためです。マクロが拡張されると、次の定義が含まれています。

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

したがって、オブジェクトがある場合 x タイプの T そしてオブジェクト y タイプの U, 、 呼び出し x->qt_check_for_QOBJECT_macro(y) 関数を呼び出します qYouForgotTheQ_OBJECT_Macro タイプのパラメーター付き T*U*. 。関数は単一のタイプパラメーターでテンプレートされているため、タイプ TU 同じでなければなりません。

今、あなたが電話するなら x->qt_check_for_QOBJECT_macro(x) 次に、タイプが同じであり、コンピレーションが簡単に成功することを期待する必要があります。ただし、それを覚えておいてください this クラスと同じタイプを持っています方法は定義されていました。 x Tから派生したが、それ自体の定義を含んでいないクラスのものです qt_check_for_QOBJECT_macro, 、呼び出しが失敗します。

そのため、ターゲットタイプTに動的キャストの正しいメカニズムが含まれているかどうかを確認する方法がありますが、このメソッドを呼び出すタイプTのオブジェクトはまだありません。それがそうです reinterpret_cast<T>(0) のためです。実際のオブジェクトは必要ありません this, 、コンパイラは、チェックが成功するためにオブジェクトタイプのみを必要とするためです。代わりに、タイプTのヌルポインターのメソッドを呼び出します。

これはC ++標準では許可されていないと思いますが、それ以降は機能します this メソッド内で実際には使用されていません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top