2011-09-16 8 views
1

私は次のデザイン問題に遭遇しています:カスタムインターフェイスの定義中にライブラリクラスを継承する

私はアプリケーションにQt C++ライブラリを使用しています。このライブラリには、すべてQAbstractItemModel(例えばQAbstractTableModel,QStandardItemModelなど)を継承する「モデル」クラスがあります。私はこれらのクラスのいくつかを継承したいが、それぞれが共有しなければならない私自身のインターフェースを定義する。

私は現在、これをやっている方法は、インターフェイス(純粋な仮想クラス)を定義して継承クラスを継承することです。例として、私はクラスがdoSomething機能を持つようにQAbstractTableModelを継承したいとしましょう:

class MyInterface { 
public: 
    virtual void doSomething() = 0; 
} 
class MyModel : public QAbstractTableModel, public MyInterface { 
    ... 
} 

しかし、私はちょうどQAbstractItemModelとして周りのオブジェクトを渡したいです。インターフェイスクラスを使用するには、オブジェクトをMyInterfaceオブジェクトにキャストしてから、関数を呼び出す必要があります。これにより、すべての場所にキャストが発生します。さらに、他の誰かがQAbstractItemModelから継承している独自のクラスを作成しても、インターフェースを継承しないとエラーの余地があるようです。

私はこのすべてを達成するために使用できるより良い設計はありますか?

答えて

0

はい。最初に、MyInterfaceクラスをまったく使用しないでください。 doSomething()メソッドを持つオブジェクトを取得する場合は、テンプレートを使用します。 "QAbstractModelとしてオブジェクトを渡す"場合は、QAbstractModel型のオブジェクトを受け付ける関数を記述していることを意味し、その一部はMyModel(またはMyInterface)ではない可能性があります。 doSomethingを呼び出すと、その関数がQAbstractModel型のオブジェクトを受け入れるという契約違反になります。

+0

オブジェクトがdoSomething()メソッドを持っていることを知るためのテンプレートシステムです。このクラスはQAbstractTableModel以上のものであることが必要です。QAbstractTableModelポインタ/参照(Qt関数など)のみが使用可能な場合はキャストが必要です - これで問題はまったく解決されません –

+0

MyInterfaceクラスは問題をまったく解決しません。 C++のすべての機能を使用して解決する前にしようとしている可能性があります。 –

+0

それは私が壊している契約についての良い考えです。それは私が全体の問題について私の立場を再考すべきだと私に思います。 – buck

0

お使いのキャストの種類は? dynamic_castを使用すると、コードの見栄えが良くなりませんが、常にnullをキャストした結果がないかどうかを確認するには、少なくともインターフェイスではないクラスのエラーの可能性があります。

これは、QAbstractTableModelからMyInterfaceに直接(動的または静的)キャストできないため、MyModelのような可能なクラスが多数ある場合にはさらに複雑になります。これらをすべてキャストしてインターフェイスにダウンキャストする必要があります後でクラス。一つの解決策は、いくつかのテンプレートのトリックでそれを行うにはあるかもしれない -

class MyInterface { 
public: 
    virtual void doSomething() = 0; 
} 

template <typename T> 
class MyTemplatedInterface: public T, public MyInterface { 
private: 
    virtual void foo(){}; // might be neceseary to be able to dynamic_cast to this type 
} 

class MyModel: public MyTemplatedInterface<QAbstractTableModel>{ 
public: 
virtual void doSomething(){}; 
} 

この方法であなたはQAbstractTableModelポインタを取得し、それはあなただけに関係なく、実際にどのような基本実装タイプで、MyTemplatedInterfaceにキャストしないMyInterfaceを実装しているかどうかを知りたい場合。このデザインには、複数のインタフェースを扱うことができない、あるいはテンプレート化されたクラスのコンストラクタを宣言できないなど、いくつかの欠陥があります。そのほとんどはC++ 0xで削除されますが、この時点ではコンパイラはそれに応じて。

+0

Qtにはダイレクトキャスティングの問題を解決する[qobject_cast](http://doc.qt.nokia.com/stable/qobject.html#qobject_cast)があります。それはちょうどまだ醜いです。 – buck

+0

MyInterfaceがQObjectを継承していない場合(そして、その多重が別のQObject-decendantで継承されている場合は不可能)、qobject_castはそれを使用できません。 –

関連する問題