以下代码有4个类:Base1、Derived1(从Base1派生(、Base2、Derived2(从Base2派生(。这两个基类都有integer 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;
}
OUPUT:
Derived1: 1 10
Base1: 2
Derived2: 3 30
Derived2: 4 40
下面是我尝试用一种简单的方式来解释它:(
当对象与基于对象的静态类型(了解其类的类型(的成员函数相关联时,就会发生静态绑定。
当指针或引用与基于对象的动态类型的成员函数关联时,就会发生动态绑定(在运行时了解变量的实例(。
继续阅读之前:动态绑定仅适用于基类的指针或引用以及虚拟函数。
第一个调用是静态绑定(也称为早期绑定(,因为调用函数所需的一切都是已知的在编译时。
Derived1 d1(1, 10);
d1.display_data();
您知道d1
实例是类型为Derived1
的自动变量,然后它将调用方法CCD_ 3。
- 第一个条件不好:d1不是指针,也不是引用
- 则第二条件不OK:CCD_ 4不是虚拟的
第二次调用
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:CCD_ 18是虚拟的
对于第四次呼叫
Base2* d4 = new Derived2(4, 40);
d4->display_data();
这一次是动态绑定。
- 第一个条件是可以的:d4是一个指针
- 第二个条件是OK:CCD_ 19是虚拟的。因此,它将调用该方法,而不是从声明的类型
base2
调用该方法从运行时声明的实例Derived2::display_data