0

以下代码有 4 个类:Base1、Derived1(派生自 Base1)、Base2、Derived2(派生自 Base2)。两个基类都有整数 data1 和 display_data() 函数。两个派生类都有整数 data1 和 data2,以及 display_data() 函数。

我在我的代码中尝试了 4 种情况,可以在 main 函数中看到。我无法确定其中哪些是静态绑定的情况,哪些是动态的。我需要一些帮助。我也想知道,这些情况中的哪些可以被认为是“函数覆盖”。

代码

#include <iostream>
using namespace std;

class Base1{
protected:
    int data1;

public:
    Base1(int idata1 = 0) {
        data1 = idata1;
    }

    void display_data() {
        cout << "Base1: " << data1 << endl;
    }
};

class Derived1 : public Base1 {
protected:
    int data2;

public:
    Derived1(int idata1 = 0, int idata2 = 0) {
        data1 = idata1;
        data2 = idata2;
    }

    void display_data() {
        cout << "Derived1: " << data1 << ' ' << data2 << endl;
    }
};


class Base2 {
protected:
    int data1;

public:
    Base2(int idata1 = 0) {
        data1 = idata1;
    }

    virtual void display_data() {
        cout << "Base2: " << data1 << endl;
    }
};

class Derived2 : public Base2 {
protected:
    int data2;

public:
    Derived2(int idata1 = 0, int idata2 = 0) {
        data1 = idata1;
        data2 = idata2;
    }

    void display_data() {
        cout << "Derived2: " << data1 << ' ' << data2 << endl;
    }
};

int main()
{
    // case 1
    Derived1 d1(1, 10);
    d1.display_data();

    // case 2
    Base1* d2 = new Derived1(2, 20);
    d2->display_data();

    // case 3
    Derived2 d3(3, 30);
    d3.display_data();

    // case 4
    Base2* d4 = new Derived2(4, 40);
    d4->display_data();

    return 0;
}

输出

Derived1: 1 10
Base1: 2
Derived2: 3 30
Derived2: 4 40
4

1 回答 1

1

这是我尝试以简单的方式解释它:)

当对象与基于对象的静态类型的成员函数关联时发生静态绑定(了解其类的类型)。

当指针或引用与基于对象的动态类型的成员函数相关联时发生动态绑定(在运行时了解变量的实例)。

继续阅读之前:动态绑定仅适用于指针或引用以及基类的虚函数。

第一个调用是静态绑定(也称为早期绑定),因为调用函数所需的一切在编译时都是已知的。

    Derived1 d1(1, 10);
    d1.display_data();

您知道d1实例是类型的自动变量,Derived1然后它将调用方法Derived1::display_data()

  • 第一个条件不行:d1 既不是指针也不是引用。
  • 第二个条件不行:Derived1::display_data不是虚拟的。

第二次通话

    Base1* d2 = new Derived1(2, 20);
    d2->display_data();

我们看到变量的声明类型d2是 ofBase1但实例是 of Derived1(它是正确的,因为继承因此Derived1是一个Base1类)。但是您还不知道display_data它将调用的方法是否是来自Base1::display_datao 的那个 Derived1::display_data

  • 第一个条件是可以的,因为我们有d2指针类型Base1*
  • 第二个条件不行,因为Base1::display_data它不是虚拟的。因此它仍然是一个静态绑定,然后将调用的函数是具有声明类型的函数,因此代码将调用Base1::display_data

第三次通话

    // case 3
    Derived2 d3(3, 30);
    d3.display_data();

这将导致静态绑定,然后调用Derived3::display_data

  • 第一个条件不行:d3 既不是指针也不是引用。
  • 第二个条件OK:Derived2::display_data是虚拟的。

对于第四次通话

    Base2* d4 = new Derived2(4, 40);
    d4->display_data();

这次是动态绑定。

  • 第一个条件是可以的:d4 是一个指针。
  • 第二个条件OK:Derived2::display_data是虚拟的。因此base2,它不会从声明的类型调用方法,而是在运行时从声明的实例调用方法Derived2::display_data
于 2021-03-23T14:53:38.707 回答