3

欢迎进行能更好地概括问题的标题编辑。

我想以某种方式重构这三个类以删除其中表示的重复字段class C(请参阅层次结构)。我想过将字段拉到父类中,但问题是 A 和 B 不够相似,不能被认为是“is-a”,C 被认为是两者,它实际上只是一个成员字段,所以创建一个类仅仅持有一件事似乎有点矫枉过正。

等级制度:

(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

看看这个问题和答案:摆脱丑陋的 if 语句清楚地表明,正如@Andre 所提到的,您当前的代码是完全可以接受的,并且试图“修复”它可能会导致同样的痛苦和心灵打击。

保持原样,这很好。

于 2012-06-16T22:21:15.080 回答
0

由于C将相同的name参数传递给Aand B,因此您可以通过虚拟继承获得所需的内容。V下面被定义为 、 和 的公共基类AB但是C通过虚拟继承,它们都共享同一个实例。

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 回答