2

以前にこの問題について投稿したことがあります (ここ)、これは解決策への別のアプローチです。この解決策は、明示的にアップキャストする必要がなくなるため、クラスを実装する人々の動作をより適切にカプセル化するようです。

問題は次のとおりです。

派生オブジェクトを介して追加の動作を提供しながら、ほとんどのオブジェクトでコア動作を分離したいプロジェクトがあります。簡単です:

class BaseA
{
    virtual void something() {}
}


class DerivedA : public BaseA
{
    void something() {}
    void somethingElse() {}
}

ここで、上記のクラスを集約することを除いて同じ継承スキームの 2 番目のクラス セットもあるとします。ただし、基本バージョンは基本クラスを使用し、派生バージョンは派生クラスで使用したいと考えています。私の解決策は、同じ名前を使用して基本クラス変数を「隠す」ことを考えていました。

class BaseB
{
    BaseA *var;

    BaseB()
    {
        var = new BaseA();
    }

    virtual void anotherThing1();
    virtual void anotherThing2();
    virtual void anotherThing3();
}

class DerivedB : public BaseB
{
    DerivedA *var;

    DerivedB()
    {
        var = new DerivedA();
    }

    void anotherThing1();
    void anotherThing2();
    void anotherThing3();
    void andAnother1();
    void andAnother2();
}

このアプローチの目標は、派生した集約クラスに依存する関数が、取得した機能を実現するために明示的にキャストする必要がなくなるようにすることです。

void func1( BaseB &b )
{
    b.anotherThing1();
    b.var->something();
}

void func2( DerivedB &b )
{
    b.anotherThing1();
    b.andAnother1();
    b.var->something();
    b.var->somethingElse();
}

void main( int argc, char **argv )
{
    BaseB    baseB;
    DerivedB derivedB;

    func1( baseB );
    func1( derivedB );
    func2( derivedB );
}

これは悪い習慣と見なされますか?

4

1 に答える 1

1

これは悪い習慣と見なされますか?

varはい、 は使用されないため、悪い習慣Baseです。DerivedBから派生する必要があるようには見えませんBaseB: 代わりに、次のように同じ抽象基本クラスから派生する必要があります。

class AbstractB {
public:
    virtual void anotherThing1() = 0;
    virtual void anotherThing2() = 0;
    virtual void anotherThing3() = 0;
};
class DerivedB1 : public AbstractB { // Former BaseB
    BaseA *var;

public:
    DerivedB1() {
        var = new BaseA();
    }
    virtual void anotherThing1();
    virtual void anotherThing2();
    virtual void anotherThing3();
};
class DerivedB2 : public AbstractB { // Former DerivedB
    DerivedA *var;
public:
    DerivedB2() {
        var = new DerivedA();
    }
    void anotherThing1();
    void anotherThing2();
    void anotherThing3();
    void andAnother1();
    void andAnother2();
};

ここで使用される一般的な原則は、継承階層内のすべての非リーフ クラスを抽象化することを試みることです。

于 2013-07-09T15:42:49.033 に答える