2016-03-15 3 views
7

に共通のメンバーを入れて:C++ - 以下のクラス階層を含むライブラリをしてみましょう二つのサブクラス

class LuaChunk 
{ 
}; 

class LuaExpr : public LuaChunk 
{ 
}; 

class LuaScript : public LuaChunk 
{ 
}; 

今、私はこれらの2つのクラスを拡張することで、自分のアプリケーションでこのライブラリを使用したいと思います:

class AppLuaExpr : public LuaExpr 
{ 
private: 

    Foo * someAppSpecificMemberFoo; 
    Bar * someAppSpecificMemberBar; 
}; 

class AppLuaScript : public LuaScript 
{ 
private: 

    Foo * someAppSpecificMemberFoo; 
    Bar * someAppSpecificMemberBar; 
}; 

ここで問題になるのは、メンバーが多く、それぞれが独自のゲッター/セッターのペアを持っていると、多くのコードの複製が生成されることです。

AppLuaExprAppLuaExprに含まれるアプリケーション固有のものを共通に入れるために、複数の継承(避けたい)を使用しない方法がありますか?

私はWikipediaに掲載されている既存の構造設計パターンを見てきましたが、これらは私の問題に適合しているようには見えません。

ありがとうございます。

+2

*構成*の使用はどうですか?共通のメンバーとコードでクラスを作成し、それを具体クラスのメンバーとして追加しますか? – Louen

+0

@ルーアンご協力いただきありがとうございます。はい、それは選択肢のようです。他のアイデア? – Virus721

+0

@songyuanyaoいいえ私はそれをすることはできません。私が言及したように、上で説明した最初の3つのクラスはライブラリ内にあり、アプリケーション固有のものを追加することはできません。そうでなければ、もはやライブラリではありません。 – Virus721

答えて

5

共通のデータを独自のクラスとして表現し、構築中に渡すことができます。そうすれば、あなたは全てを合成してカプセル化することができます。

class Core { }; 

class Component { 
    int one, two; 
public: 
    Component(int one, int two) : one(one), two(two) 
    {} 
}; 

class Mobious : public Core 
{ 
    Component c; 
public: 
    Mobious(Component &c) : Core(), c(c) { } 
}; 

class Widget : public Core 
{ 
    Component c; 
public: 
    Widget(Component &c) : Core(), c(c) 
    {} 
}; 

int main(void) 
{ 
    Widget w(Component{1, 2}); 
    Mobious m(Component{2, 3});; 
    return 0; 
} 
+0

ご協力いただきありがとうございます。私は、コンポジットは私が使うつもりだと思う。 – Virus721

+0

@ Virus721一度しか初期化されていないが、両方のクラスで使用される依存関係がある場合は、それを表現するために 'shared_ptr'(スマートポインタ)を使うことを検討してください。これは、リソースがアプリケーション内で一度だけ初期化され、破棄されることを保証するのに役立ちます。 – Johannes

+1

@ Virus721記録のために、これは*コンポジション*(メンバーを使用するクラスに対するデリゲート機能)と*コントロールの逆転*(コンストラクタ内で委譲先クラスを渡す)を使用します。 – MicroVirus

関連する問題