2016-11-09 14 views
2

QtクラスはパブリッククラスにQ_DECLARE_PRIVATEマクロを持っています。マクロは、読み取ります。ここQ_DECLARE_PRIVATEマクロを定義中にreinterpret_castが実装d_fun()で使用される理由

#define Q_DECLARE_PRIVATE(Class)\ 
    inline Class##Private* d_func() {\ 
     return reinterpret_cast<Class##Private*>(qGetPtrHelper(d_ptr));\ 
    }\ 
    inline const Class##Private d_func() const {\ 
     return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr));\ 
    }\ 
    friend class Class##Private; 

、私の理解Class##Privateあたりとしてd_ptrのクラスの親、なぜreinterpret_castが使用されていないdynamic_castでしょうか?

+0

親クラスの場合、 – StoryTeller

+0

@StoryTellerのキャストは必要ありません。間違いなく、Qt pimplイディオムは明示的にhiearchiesについて何も想定できません。マクロは任意の消費コードで動作する必要があるAPIです。 – user268396

+0

@ user268396、私のコメントはあなたの言ったことと矛盾していますか? – StoryTeller

答えて

1

dynamic_castには、少なくとも1つのvirtualメソッド(多態性が必要)が必要です。 dynamic_castが成功するにはクラス継承だけでは不十分です。

+0

PIMPLクラスは通常、基本クラスへのポインタを介して破棄されるため、仮想デストラクタを持つ必要があります。そうではありません。一つの大きな理由の一つは 'dynamic_cast'はQtのソースコードではサポートされていないということです。 'dynamic_cast'はQt 5.7.0ソースの約十十箇所に現れ、それらはすべて本質的にバグ/省略です。 –

3

理由は次のとおりRTTIがオフとQtが構築できるよう

  1. dynamic_castは、Qtのソースコードでサポートされていません。

    dynamic_cast<文字列は、テストされていない第三者のQt 5.7.0ソースで約12箇所に表示され、そのほとんどは本質的にバグ/省略です。

  2. マクロは、Class##Privateが前方定義のヘッダーで使用されます。コンパイラはClass##Privateが指し示された型d_ptrから派生していることを知らないため、static_castは機能しません。

  3. Class##Privateがフォワード定義されていない場合、正しいキャストはstatic_castになります。コンパイル時にd_ptrの指し示し型がわかっているところでマクロが使用されているため、ヘッダーにはなりませんが、dynamic_castは時期尚早の悲観化になります。 Q_DECLARE_PRIVATEの詳細については

は、またHow to use the Qt's PIMPL idiom?参照してください。

+0

@Kuba Ober:なぜ 'static_cast'もうまくいかない理由を説明してくれてありがとう。 – Sajal