【问题标题】:Public virtual method overridden as protected in inherited class在继承的类中被重写为受保护的公共虚拟方法
【发布时间】:2014-01-08 12:15:03
【问题描述】:

我在 C 类中定义了一个受保护的抽象虚方法 myMethod()。D 类继承自 C 并定义了 myMethod()。现在类 E 也继承自 C 并且还定义了myMethod()。所以我有这样的事情:

看起来像这样

class C
{
protected:
    virtual void myMethod() = 0;
}

class D : public class C
{
protected:
    void myMethod() {/*Do something*/};

    void anotherMethod();
}

class E : public class C
{
protected:
    void myMethod() {/*Do something else*/};
}

现在如果在D::anotherMethod() 中有一个指向E 类对象的指针,那么我不能调用E::myMethod()。这里没有错:D 和 E 具有不同的层次结构,因此我不能从 D 调用 E::myMethod()。即以下代码无法编译,这是预期的:

void D::anotherMethod()
{
    E* myE = new E();

    myE->myMethod();
}

现在,如果我更改 C 的声明并将 E::myMethod() 公开(同时保留 D 和 E 中的重写方法 protected),例如在下面的代码中,它会编译:

class C
{
public:
    virtual void myMethod() = 0;
}

class D : public class C
{
protected:
    void myMethod() {/*Do something*/};

    void anotherMethod();
}

class E : public class C
{
protected:
    void myMethod() {/*Do something else*/};
}

我只在 C 内部将 public 更改为 protected,而不是在继承的 D 和 E 类中。

有谁知道它为什么会编译,背后的逻辑是什么?

谢谢!

安托万。

【问题讨论】:

  • 我认为,你的设计很糟糕。为什么你需要隐藏一个被你的接口声明为公共的方法?此外,如果 D 从 C 派生,则 D 是 C,E 是 C。为什么 D 应该包含 E?
  • 你好,dousin,这是一个层次结构,D是一个分支,E是一个叶子:分支可以包含叶子......至于“糟糕的设计”,你可能是对的,我可能需要是否重新考虑我的架构。但首先我想了解更多关于我观察到的意外行为。

标签: c++ inheritance polymorphism


【解决方案1】:

我们可以使用C 接口,因为它是公共的: E 接口受保护,D 无法从 E 访问,但可以从基类 C 访问

如下:

class C
{
public:
    virtual void myMethod() = 0;
};

class E : public C
{
protected:
    void myMethod() {/*Do something else*/};
};


class D : public C
{
protected:
    void myMethod() {/*Do something*/};

    void anotherMethod(){
        //C* myE = new E(); // does compile
        E* myE = new E(); // doesn't compile

        myE->myMethod();
    }
};

【讨论】:

  • 您好 Jarod42,不确定这是否是特定于编译器的,但您提到的代码确实可以使用我的 MSVC 2008...
  • 所以我认为它应该是 msvc 的错误/扩展。
猜你喜欢
  • 1970-01-01
  • 2015-05-16
  • 2018-08-23
  • 2016-03-17
  • 2012-08-19
  • 1970-01-01
  • 2016-01-01
  • 2013-02-14
  • 2013-04-26
相关资源
最近更新 更多