3

あいまいなタイトルで申し訳ありません。

私は一連のクラスを書いていますが、基本コンストラクターで行われることと派生コンストラクターで行われることを直感的に分割する方法を考えるのに苦労しています。

私の問題は次のとおりです。

すべてのクラスで、手順 A、C、および E を順番に完了する必要があります。したがって、それらを基本コンストラクターに配置することは理にかなっています。

ステップ B と D は、各派生クラスに固有です。

残念ながら、B はA の後、C のに完了する必要があり、同様に、D はCの後、E の前に完了する必要があります。これらは OpenGL の関数呼び出しであり、それらの順序には制約があります。

私はもともと、基本クラスで可能な限りカプセル化することを望んで、これに沿って何かを試しました:

public class MyBase
{
    MyBase()
    {
        A():
        B();
        C();
        D();
        E();  
    }
    void A() {...}
    void C() {...}
    void E() {...}
    virtual void B() = 0;
    virtual void D() = 0;
}

public class MyDerived : public MyBase
{
    MyDerived() : MyBase() {}
    void B() {...}
    void D() {...}
}

しかし、それはC++では不可能です...

これ以外にこれを行うより直感的な方法はありますか:

public class MyBase
{
    MyBase() {}
    void A() {...}
    void B() {...}
    void C() {...}
}

public class MyDerived : public MyBase
{
    MyDerived()
    {
        A():
        B();
        C();
        D();
        E();  
    }
    void B() {...}
    void D() {...}
}

コードの繰り返しをできるだけ避けたいと思っています。

何か案は?

4

2 に答える 2

0

コンストラクターで仮想関数を呼び出すことは危険である可能性があることを考えると、マクロを使用することはあなたにとって受け入れられる解決策ですか?

#define MY_BASE_INIT A();B();C();D();E();

public class MyBase
{
    MyBase() {}
    void A() {...}
    void C() {...}
    void E() {...}
}

public class MyDerived : public MyBase
{
    MyDerived()
    {
        MY_BASE_INIT
    }
    void B() {...}
    void D() {...}
}
于 2013-02-20T02:53:16.527 に答える
0

確実にコンストラクターで呼び出したいが、後で呼び出しても問題ない場合は、以下を実行することで混乱を少し減らすことができます。

public class MyBase
{
    protected:
    void templateMethod()
    {
        A():
        B();
        C();
        D();
        E();  
    }
    private:
    void A() {...}
    void C() {...}
    void E() {...}
    virtual void B() = 0;
    virtual void D() = 0;
};

public class MyDerived : public MyBase
{
    MyDerived() : MyBase() {templateMethod();}
    void B() {...}
    void D() {...}
};

ただし、これは完全に真のテンプレート メソッド パターンではありません。これは、基本クラスに対して 1 回呼び出されるのではなく、すべての派生クラスが呼び出す必要があるためです。

于 2013-02-20T02:02:27.233 に答える