2016-06-27 15 views
0

私はこのようなヘッダーファイルにインターフェイスクラスを持っています。私は自分のアプリケーションの周り渡される私のインタフェースを実装するオブジェクトへのポインタを持っているこのインターフェイスからQObjectへのキャスト

class Implementation : public QWidget, public Interface 
{ 
    Q_OBJECT 
    Q_INTERFACES(Interface) 
    ... 
} 

のように実装されることが期待される

class Interface 
{ 
... 
} 
#define InterfaceIID "Interface" 
Q_DECLARE_INTERFACE(Interface, InterfaceIID) 

。今、私はすべてのInterfaceオブジェクトもQWidgetであることを知っています。なぜなら、これは唯一サポートされているユースケースなのでです。

QWidgetオブジェクトが必要なときに、私のインターフェイスオブジェクトをQWidgetにキャストするにはどうすればよいですか?

qobject_cast<QWidget*>(interface) //does not compile 
dynamic_cast<QWidget*>(interface) //works but is it the right way? 

dynamic_cast()は唯一の方法ですか? Qobject_cast()を使用してQWidgetからInterfaceにキャストできますが、逆は機能しません。

私はdynamic_cast()が共有ライブラリ全体で安全でないことを理解していますので、避けようとしています。

正しいアプローチは何ですか?

+0

'Impllemntation'に' Interface'をキャストしてから 'Implementation'を' QWidget'にキャストしてください。私は 'Interface'が' QWidget'にキャストできるのは疑いがあります。なぜなら、それらは同じ継承チェーンの一部ではないようです。 – rozina

+0

@rozina QWidgetはInterfaceの基本実装である可能性があります(コードから分かりません)ので、Interface *からQWidget *へのキャストが機能する可能性があります。 dynamic_castは答えを安全に与えます。 – Neil

+0

@rozina残念ながら、私はそれをすることはできません。このキャストが発生した場合、コードは実装を認識しません。インタフェースを知っているだけで、実装がQWidgetから継承されていると仮定して文書化されています。 –

答えて

1

もう1つは正しいです。 qObjectCastは、QObjectを「何か」にキャストするためのものであり、他の方法ではありません。ザッツは動的なものをキャストするためのものである:

QObject *intfObject = pluginLoader.instance(); 
Interface *intf = qobject_cast<Interface *>(intfObject);//only works if the object has Q_INTERFACES(Interface) 
QWidget *intfWidget = dynamic_cast<QWidget*>(intf); 

注:上記のqobject_castを簡単dynamic_castに置き換えることができます。ただし、可能であれば、常にqobject_castを使用してください。 (documentationからの)理由:

qobject_cast()関数は、標準C++のdynamic_cast()と同様の挙動の利点と、それはRTTIのサポートを必要としないこと、それは動的ライブラリの境界を越えて動作します。

Qtsメタシステム(QMetaObject)を使用してキャストを実行します。そしてそれに加えて、dynamic_castの方が速いと思われます。

qobject_castを使用してインターフェイスをQWidgetにキャストできないのは、インターフェイス自体がQObjectを継承しないためです(Q_OBJECTマクロを持たないためです)。したがって、メタオブジェクトはなく、qobject_castは使用できません。

EDIT:ダイナミックキャストを回避するために
一つの方法は、常にQObjectとしてプラグインを維持することです。ウィジェットとして必要な場合は、qobject_castでキャストしてください。 Interfaceでも同じです。インスタンスを格納/通過する限り、QObjectとして、あなたはdynamic_castする必要はありません。

注:プラグインの種類を知る必要がある場合は、インターフェイスごとに小さなラッパークラスを作成します。

+0

それでは、dynamic_cast()を使用するのは安全ですか?インターフェイスと、キャストを行うコードは、私の場合はメインアプリケーションの1つのライブラリにあり、実装は別のライブラリ(プラグイン)からのものです。 –

+0

私が知る限り、はい。 Qtはプラグインを「正しい方法」でロードするためです。少なくとも私にとってダイナミックなキャストは常に今のところ働いています。しかし、あなたがその解決策で不愉快に感じる場合は、編集した投稿をチェックしてください。 – Felix

関連する問題