【问题标题】:Polymorphism in C++C++中的多态性
【发布时间】:2013-03-01 04:53:48
【问题描述】:

好的,所以我知道有很多多态线程飞来飞去,但我还没有遇到这种情况。

class Base {
public:
    virtual void method1() {
        cout << "BaseMethod1" << endl;
    }

    void method2() {
        cout << "BaseMethod2" << endl;
    }
};

class Derive: public Base {
public:
    void method1() {
        cout << "DeriveMethod1" << endl;
        method2();
    }

    void method2() {
        cout << "DeriveMethod2" << endl;
    }
};

int main() {
    Base* p = new Derive();
    p->method1();
}

让我感到困惑的是派生类中的method1调用了method2。那么,既然 Base 类中的 method2 没有声明为 virtual,那么它会是哪个 method2?

提前谢谢!

【问题讨论】:

  • method2() 括号丢失,如果我没记错的话
  • @Pubby 尝试的东西不一定会导致 C++ 的启蒙。事实上,在发生未定义行为的情况下,它可能会导致一种危险的错误安全感。
  • 回答这个问题要查找的关键词是"name hiding"
  • -1。首先做一个基础研究,因为这是一个非常基础的问题,问编译器,然后可能问一个更具体的问题。
  • @Antimony 如果您喜欢阅读该标准,那就按照自己的方式来吧。我只关心人们在提问之前做一些研究。

标签: c++ polymorphism


【解决方案1】:

由于Base::method1() 被声明为private,相关代码将无法编译。 它必须是public 才能从main 调用。


Derived::method1() 隐含为virtual,即使未标记为virtual。所以Derived::method1() 中的this 指向Dervied 对象,在这个范围内编译器只能看到Derived::method2()。因此Derived::method2() 将被调用。派生类中的方法隐藏基类中同名的方法。


好读:

What's the meaning of, Warning: Derived::f(char) hides Base::f(double)?

【讨论】:

    【解决方案2】:

    您不经常看到这种模式的主要原因是它实际上是一种反模式。

    将调用 Derived 方法,因为您使用 Derived 对象引用 (this) 调用它。如果您使用 Base 类引用调用它,您将获得 Base 方法。

    如果您重新声明了一个非虚拟方法,您将隐藏基本方法并破坏多态性。

    【讨论】:

    • +1 有几个优点(特别是this 的意义),但关于“重新声明非虚拟方法 [is] 破坏多态性” - 这有点夸张:对象可能会继续工作通过基类引用/指针完全多态地进行多态 - 根据 Liskov 替换原则 - 或者甚至可能不需要一些虚拟函数以避免违反原则(例如,不能根据 Base 方法解析的派生类序列化方法文档)。没有损坏,但很脆弱(例如,更难切换到编译时多态性)。
    • 好点。几乎总是有例外的规则。我倾向于非常坚持这个特定的规则,因为它减少了大型代码库中出错的可能性。这与人们的预期相矛盾。我想你可以说它夸大了多态性,因为现在你正在制作一个根据你引用它的方式采取多种形式的对象:P。
    【解决方案3】:

    它将使用Derive::method2() 作为名称查找(在Derive::method1() 的主体中)从类本身开始。

    【讨论】:

      猜你喜欢
      • 2016-06-28
      • 2017-10-21
      • 1970-01-01
      • 1970-01-01
      • 2013-04-24
      • 1970-01-01
      • 1970-01-01
      • 2012-09-26
      相关资源
      最近更新 更多