C++ 静态绑定与动态绑定

1、静态类型与动态类型

C++中由于继承导致对象的指针和引用具有两种不同的类型,静态类型和动态类型。

对象的静态类型:对象在声明时采用的类型,在编译时确定;

对象的动态类型:目前所指对象的类型,在运行期时确定。

特别说明:静态类型是,指针或引用声明时的类型;动态类型是,指针或引用实际指向的类型。

静态绑定:绑定的是对象的静态类型,(函数)依赖于对象的静态类型,发生在编译时期

动态绑定:绑定的是对象的动态类型,(函数)依赖于对象的动态类型,发生在运行时期

特别说明:virtual构成动态绑定,no-virtual构成静态绑定。

相关概念:

a.重写(override)

        override指基类的某个成员函数为虚函数,派生类又定义一成员函数,除函数体的其余部分都与基类的成员函数相同。注意,如果只是函数名相同,形参或返回类型不同的话,就不能称为override,而是hide。

b.重载(overload)

        指同一个作用域出生多个函数名相同,但是形参不同的函数。编译器在编译的时候,通过实参的个数和类型,选择最终调用的函数。

c.隐藏(hide)

分为两种:1)局部变量或者函数隐藏了全局变量或者函数;2)派生类拥有和基类同名的成员函数或成员变量。

 产生的结果:使全局或基类的变量、函数不可见。

2、virtual如何构成动态绑定

首先,虚函数是通过虚函数指针与虚函数表实现的。虚函数指针位于对象内存首地址,指向所属对象的虚函数表(这句话是实现动态绑定的关键)。

例如:

class B:public A{};

B b;

A *p=&b;

父类指针p指向子类B的对象时,指针p静态绑定了A类,便只能访问A内成员,但是!!!!!当p调用虚函数时,会默认调用虚函数指针,又因为虚函数指针指向的是对象的虚函数表。这里需要清楚两个点:1、 A *p 时并没有分配内存,而A *p = new A ()才分配了内存;2、虚函数指针是能是在对象b的内存中。此时,通过父类指针p调用虚函数时,便访问了子类对象中的成员函数,从而实现了动态绑定!!!

3、特殊情况

缺省参数(指定了个固定值)和虚函数一起时的复杂情况,虚函数是动态绑定,但为了执行效率缺省参数是静态绑定。

 

你可能感兴趣的:(C++ 静态绑定与动态绑定)