提问者:小点点

C++中静态和动态绑定的实例


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

我在我的代码中尝试了4个案例,可以在主函数中看到。我不知道哪一个是静态绑定,哪一个是动态绑定。我需要一些帮助。我还想知道,这些情况中哪些可以认为是“函数重写”。

代码:

#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

共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的声明类型是base1的,但实例是derived1的(这是正确的,因为继承,因此derived1是一个base1类)。但您还不知道它将调用的display_data方法是来自base1::display_data的方法还是来自derived1::display_data的方法。

  • 第一个条件是可以的,因为我们有类型指针base1*D2
  • 第二个条件不确定,因为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();

这一次是动态绑定。

  • 第一个条件是OK:d4是指针。
  • 第二个条件是OK:derived2::display_data是虚拟的。因此,它不是从声明的类型base2调用方法,而是在运行时derived2::display_data
  • 从声明的实例调用方法

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(c++|中|静态|动态|绑定|实例)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?