【问题标题】:How reassigning pointers affects polymorphism重新分配指针如何影响多态性
【发布时间】:2020-07-16 04:31:14
【问题描述】:

这是我想知道的事情。有 2 个指针对应 2 个类实例。该代码打印出 6 行(根据 cmets)。前 4 行对我来说是有意义的,但我不明白后 2 行。我希望第 5 行和第 6 行等于第 3 行和第 4 行,因为 pbpd 现在都指向同一个对象。请帮我理解。

#include <iostream>

using namespace std;

class B {
public:
  virtual void run1(){cout << "Base" << endl;}
  void run2(){cout << "Base" << endl;}
};

class D: public B {
public:
  virtual void run1(){cout << "Derived" << endl;}
  void run2(){cout << "Derived" << endl;}
};

int main(int argc, char* argv[])
{
  B b, *pb;
  D d, *pd;

  pb = &b;
  pb->run1(); //Base
  pb->run2(); //Base

  pd = &d;
  pd->run1(); //Derived
  pd->run2(); //Derived

  pb = &d;
  pb->run1(); //Derived (why ?)
  pb->run2(); //Base    (why ?)
}

【问题讨论】:

    标签: c++ class inheritance polymorphism virtual-functions


    【解决方案1】:

    函数run1是一个虚函数,而函数run2不是一个虚函数。

    虚函数根据使用指针的动态类型调用,非虚函数根据使用指针的静态类型调用。

    指针pb的静态类型为B *

      B b, *pb;
    

    这次分配之后

    pb = &b;
    

    指针的动态类型也是B *。于是类B中定义的虚函数就被调用了。

    这次分配之后

    pb = &d;
    

    指针pb的动态类型由B *更改为D *

    所以在这个声明中

    pb->run1(); //Derived (why ?)
    

    根据指针的动态类型称为虚函数。而在此声明中

    pb->run2(); //Base    (why ?)
    

    根据指针的静态类型调用非虚函数。

    即在使用的指针指向的对象中查找指向虚函数指针表的指针。

    此功能定义了多态行为。

    【讨论】:

    • 太棒了。感谢您的解释。这就说得通了。所以,我想它归结为指向对象的指针的编译时(静态)与运行时(动态)链接也是准确的?
    • 指针的动态类型(技术上没有这样的东西,但我明白你的意思)是它的静态类型(或只是类型),就像任何其他标量类型一样。
    • @curiousguy 来自 C++ 标准“如果静态类型为“指向 B 类的指针”的指针 (8.3.1) p 指向从 B 派生的 D 类对象(第 10 条) ,表达式 *p 的动态类型是“D”。参考文献(8.3.2)的处理方式类似。-"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 2017-09-16
    • 2013-01-07
    • 2015-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多