9

MyClassQt 組み込みオブジェクト ( ) からほとんどの機能を継承するクラス ( ) がありますQGraphicsTextItemQGraphicsTextItemから間接的に継承しQObjectます。MyClassインターフェースも実装していますMyInterface

class MyClass : public QGraphicsTextItem, public MyInterface

connectdisconnectonを使用できる必要がありますMyInterface*。しかし、インスタンスconnectdisconnectのみ機能するようです。QObject*Qt は QObject 派生クラスからの多重継承をサポートしていないため、から派生できませMyInterfaceQObject。(とにかく、それはインターフェイスにとってあまり意味がありません。)

オンラインで問題についての議論がありますが、IMO 提案された解決策は、信号とスロットを接続することはできませんがMyInterface*、派生型にキャストする必要があるため、一般的なケース (インターフェイスを介してオブジェクトにアクセスする) ではかなり役に立ちません。MyClassは多くの 派生クラスの 1 つであるためMyInterface、これは「コード臭い」if-this-cast-to-this-else-if-that-c​​ast-to-that ステートメントを必要とし、インターフェイスの目的を無効にします。

この制限に対する適切な解決策はありますか?

更新:もし私dynamic_castMyInterface*to QObject*(すべての派生クラスも最終的に から継承することを知っているので、それはうまくいくようです.つまり:MyInterfaceQObject

MyInterface *my_interface_instance = GetInstance();
connect(dynamic_cast<QObject*>(my_interface_instance), SIGNAL(MyInterfaceSignal()), this, SLOT(TempSlot()));

しかし、これは本当に未定義の動作を求めているようです....

4

2 に答える 2

12

あなたは自分で答えを見つけました:dynamic_castはあなたが期待するように機能します。未定義の動作ではありません。取得したMyInterfaceのインスタンスがQObjectでない場合、キャストはnullを返し、それから身を守ることができます(インターフェイスのすべてのインスタンスもQObjectであると言ったので、これは起こりません)。ただし、RTTIを機能させるには、RTTIをオンにする必要があることに注意してください。

他にもいくつか提案します。

  • Q_INTERFACES機能を使用します(プラグインだけではありません)。次に、QObjectの観点から作業し、本当に必要なときにqobject_castを使用してMyInterfaceをクエリします。問題の詳細はわかりませんが、すべてのMyInterfaceインスタンスもQObjectであることがわかっているので、これが最も賢明なアプローチのようです。

  • QObject* asQObject()MyInterfaceに抽象メソッドを追加し{ return this; }、すべてのサブクラスと同様に実装します。

  • 1つ(継承)ではなく、QGraphicsTextItem(構成)を持つ。

于 2010-07-17T23:00:53.520 に答える
7

コンストラクターで QObject を取る MyInterface を宣言できます。

class MyInterface {
public:
                MyInterface(QObject * object);
    QObject *   object() { return m_object; }
    ...
private:
    QObject *   m_object;
};

MyInterface::MyInterface(QObject * object) :
    m_object(object)
{
    ...
}

次に MyClass コンストラクターで:

MyClass::MyClass() :
MyInterface(this)
{
    ...
}

そして、信号を接続できます:

MyInterface *my_interface_instance = GetInstance();
connect(my_interface_instance->object(), SIGNAL(MyInterfaceSignal()), this, SLOT(TempSlot()));
于 2010-07-15T22:09:17.900 に答える