3

質問のより良い要約を反映するタイトル編集は大歓迎です。

これらの3つのクラスを何らかの方法でリファクタリングして、で表される重複フィールドを削除したいと思いclass Cます(階層を参照)。フィールドを親クラスにプルアップすることを考えましたが、問題は、AとBが「is-a」と見なされるほど類似しておらず、Cが両方と見なされ、文字通り1つのメンバーフィールドであるため、クラスを作成することです。一つのことを保持するだけでは少しやり過ぎのようです。

階層:

(abstract data type)
class A : public O {
    public:
    //...
    std::string GetName();
    std::string GetName() const;
    void SetName(std::string name);
    //...
    protected:
    //...
    std::string _name;
    //...
};

//Methods and fields shown here represent the exact same representative data as in A but the classes are so dissimilar as to not be considered "is-a" relationship.
(abstract data type)
class B {
    public:
    //...
    std::string GetName();
    std::string GetName() const;
    void SetName(std::string name);
    //...
    protected:
    //...
    std::string _name;
    //...
};

(concrete)
class C : public A, public B {
    public:
    //...
    C(/*..Other parameters..*/, std::string name, /*....*/)
    : A(name, /*...*/), B(name, /*...*/) {
        /*...*/
    }
    //...
    private:
    //...        
};
4

3 に答える 3

1

前に述べたように、そのままにするか、次のようにクラスCの継承よりも合成を使用することを検討できます。

class C : public A
{
public:
    // ...
    // The GetName and SetName methods are inherited from A.

private:
    B* b;
};

また

class C
{
public:
    // ...

    std::string GetName();
    std::string GetName() const;
    void SetName(std::string name);

private:
    A* a;
    B* b;
};
于 2012-06-16T23:13:08.900 に答える
0

この質問と回答を見てください。@Andreが述べたように、ステートメントが明確に示している場合は、醜いものを取り除きます。現在のコードは完全に受け入れ可能であり、「修正」しようとすると、同じ苦痛と心の打撃を引き起こす可能性があります。

そのままにしておいて、いいです。

于 2012-06-16T22:21:15.080 に答える
0

はとの両方に同じパラメータをC渡すので、仮想継承で必要なものを取得できる可能性があります。以下は、、、およびの共通の基本クラスとして定義されていますが、仮想継承では、これらはすべて同じインスタンスを共有します。nameABVABC

class V {
    public:
    std::string GetName();
    std::string GetName() const;
    void SetName(std::string name);
    protected:
    std::string _name;
    V () {}
    V (std::string n) : _name(n) {}
    ~V () {}
};

class A : virtual public V, public O {
    //...
};

class B : virtual public V {
    //...
};

class C : virtual public V, public A, public B {
    public:
    C (/*...otherargs,*/std::string name/*,moreargs...*/)
        : V(name), A(/*...*/), B(/*...*/) {
        //...
    }
    //...
};
于 2012-06-16T23:12:51.863 に答える