当前位置: 首页 > 知识库问答 >
问题:

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

鲜于承基
2023-03-14

下面的代码有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个答案

姬存
2023-03-14

下面是我试图用一种简单的方式来解释的:)

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

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

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

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

    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
  • 从声明的实例调用方法
 类似资料:
  • 问题内容: 我对动态绑定和静态绑定感到非常困惑。我已经读过,在编译时确定对象的类型称为静态绑定,而在运行时确定它的称为动态绑定。 下面的代码会发生什么: 静态绑定还是动态绑定? 这表明什么样的多态性? 问题答案: 您的示例是 动态绑定 ,因为在运行时确定类型是什么,并调用适当的方法。 现在假设您也具有以下两种方法: 即使您更改为 这将打印出来,因为对的调用使用 静态绑定 ,并且编译器仅知道其类型。

  • 我们知道静态绑定发生在私有、静态、最终和重载的方法上,而动态绑定发生在被覆盖的方法上。但是如果我的方法只是公共的,它既不是静态的,也不是覆盖和重载的怎么办? 有人能给我解释一下print()的绑定会怎样,因为它既没有重载也没有被覆盖。

  • 请有人给我解释一下输出的最后6行是如何打印出来的。我知道,由于静态绑定,前三行打印适当。 我不知道为什么第5行给出了输出,因为它是Ipod类型的,它没有任何歌曲方法,但它仍然打印输出。代码如下: 输出如下所示:

  • 静态绑定还是动态绑定? 这显示了什么样的多态性?

  • 起初我是一个初学者 我看过很多教程,读过很多例子,甚至试图从JLS来理解这个主题,但我仍然有一些困惑或误解。 让我给你看我看不懂的问题。

  • 本文向大家介绍java动态绑定和静态绑定用法实例详解,包括了java动态绑定和静态绑定用法实例详解的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了java动态绑定和静态绑定用法。分享给大家供大家参考,具体如下: 背景 1.当子类和父类存在同一个方法,子类重写了父类的方法,程序在运行时调用的是父类的方法还是子类的重写方法呢(尤其是存在向上类型转换的情况)? 2.当一个类中存在方法名相同但参数