-
28-10-2019 - |
質問
Qobjectのために、複数のエンヘリタンスに関してQTに問題があります。他の多くの人が同じ問題を抱えていることを知っていますが、どのように修正すべきかわかりません。
class NavigatableItem : public QObject
{
Q_OBJECT
signals:
void deselected();
void selected();
void activated();
};
class Button : public NavigatableItem, public QToolButton
{
Q_OBJECT
...
}
class MainMenuOption : public Button
{
Q_OBJECT
...
}
私がこれをするとき
MainMenuOption* messages = new MainMenuOption();
connect(messages, SIGNAL(selected()), SLOT(onMenuOptionSelected()))
エラーが発生します:
QObject 'は「メインメヌオプション」の曖昧な基盤です
信号のために、Qobjectからnavigatableitem enheritをnavigatableitemにした理由。これを行う方法はありますか?
編集:
各継承宣言に仮想を追加すると、それでも同じエラーが得られます。
class NavigatableItem : public virtual QObject
class Button : public virtual NavigatableItem, public virtual QToolButton
class MainMenuOption : public virtual Button
「すべてをきれいに」、「qmakeを実行して」、「すべてを作成」した後でも。
解決
もう少しコードが必要ですが、私が過去に行ったことはそれらの1つになります(あなたの NavigatableItem
この場合)純粋な仮想クラス、つまりインターフェイス。 「信号」マクロを使用する代わりに、純粋な仮想保護機能にします。次に、QObject由来のクラスとインターフェイスからのインタヒアを乗算し、メソッドを実装します。
私はそれがやや議論の余地があることを知っていますが、あらゆる犠牲を払って複数の実装継承を避けることは、多くの問題と混乱を解決します。 Google C ++スタイルのガイドライン これをお勧めします、そして私はそれが良いアドバイスだと思います。
class NavigatableItemInterface
{
// Don't forget the virtual destructor!
protected:
virtual void deselected() = 0;
virtual void selected() = 0;
virtual void activated() = 0;
};
class Button : public NavigatableItemInterface, public QToolButton
{
Q_OBJECT
...
signals:
virtual void deselected();
...
}
他のヒント
仮想継承を使用します
class X : public virtual Y
{
};
class Z : public virtual Y
{
};
class A : public virtual X, public virtual Z
{
};
基本クラスyのコピーは1つしかありません
仮想継承を使用する必要があります。
見る http://en.allexperts.com/q/c-1040/virtual-inheritance.htm
ダイヤモンドの問題を経験しているようです。
http://www.cprogramming.com/tutorial/virtual_inheritance.html
このようにしてください:
class NavigatableItem : public virtual QObject
class Button : public virtual NavigatableItem, public virtual QToolButton
class MainMenuOption : public Button