1

我需要通过保护基类从基类中抽象出许多接口,但我还需要对一个简单的祖先类进行公共访问Object。我是否可以在没有对这些祖先的写入/编辑访问权限的情况下协商可怕的钻石Object,并且仍然只提供一个基本 API,但再次公开 's API?

class Object {
    virtual bool  Equals (const Object &obj) const;
    virtual int  GetHashCode (void) const;
};

class ComplicatedOne : public Object {
    //Lots of funcs I don't want or need.
};

class Line : protected ComplicatedOne, public Object {
    //Some funcs of ComplicatedOne get re-implemented or called by alias here
public:
    virtual bool Equals(const Object &obj) const {
        return Object::Equals(obj);
    }
    virtual int GetHashCode() const {
        return Object::GetHashCode();
    }
};

class Array {
    void Add (Object &obj);
    Object *GetAt (int i);
};

main() {
    Array a;
    a.Add(new Line());
}
4

3 回答 3

2

你可以使用组合。

您可以将实例ComplicatedOne作为成员,并公开您需要的内容。

这样你可以保护它,但永远不会有钻石的情况。

此外,如果ComplicatedOne 是一个Object,那么Line是一个Object继承,所以你不需要再次继承。

于 2011-12-19T09:38:53.220 回答
1

您对真正的问题是什么非常模糊,但对我来说,这听起来好像您只想使用继承来获得代码重用。
你不应该这样做。看看这篇文章
对我来说,这听起来像是你想要的更多。在您的班级 Line 中创建一个成员ComplicatedOne并将呼叫委托给该成员。那么你不需要继承它。

于 2011-12-19T09:39:54.443 回答
0
    return Object::Equals(obj);

那无法编译,因为它是模棱两可的:有两个Object基础对象。

此外,从Line*to的转换Object*是模棱两可的,并且不能将歧义解决到第二个Object基类(从左到右的基类顺序),因此第二个基类Object除了制造困难之外没有任何用途。

目前尚不清楚您到底要做什么:ComplicatedOne类代表什么?Object如果要再次覆盖每个虚函数,为什么要从它继承?

于 2011-12-25T22:24:18.943 回答