【问题标题】:C++ Multiple inheritence, base class visibility and the dreaded diamond. Re-exposing ancestor base class as public?C++ 多重继承、基类可见性和可怕的钻石。将祖先基类重新公开为公共?
【发布时间】:2011-12-19 09:31:20
【问题描述】:

我需要通过保护基类从基类中抽象出许多接口,但我还需要对简单的祖先类Object 进行公共访问。我是否可以协商 dreaded diamond 而无需对这些祖先进行写入/编辑访问,并且仍然只提供一个基本 API,但再次公开 Object 的 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());
}

【问题讨论】:

    标签: c++ inheritance multiple-inheritance access-specifier


    【解决方案1】:

    你可以使用合成。

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 没错,当需要组合时,我对继承要发疯了。
      【解决方案3】:
          return Object::Equals(obj);
      

      那无法编译,因为它不明确:有两个Object 基础对象。

      另外,从Line*Object* 的转换是模棱两可的,并且不能将歧义解析到第二个Object 基类(从左到右的基类顺序),所以第二个Object 基类不会服务于任何目的,除了制造困难。

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

      【讨论】:

      • 虽然ComplicateOne 包含//Lots of funcs I don't want or need.,但它仍然有它的用途。
      猜你喜欢
      • 2013-02-14
      • 2012-04-19
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多