【C++】 理解 多态 之 静态绑定与动态绑定


为了支持C++的多态性,才用了动态绑定与静态绑定。

静态类型与动态类型

  • 对象的静态类型:

对象在声明时候的类型,是在编译时期确定的。

  • 对象的动态类型:

目标所指向的对象,是在运行期决定的。对象的动态类型可以更改,但是静态类型无法更改。

示例:

class B
{
}
class C : public B
{
}
class D : public B
{
}
D* pD = new D();//pD的静态类型是它声明的类型D*,动态类型也是D*
B* pB = pD;//pB的静态类型是它声明的类型B*,动态类型是pB所指向的对象pD的类型D*
C* pC = new C();
pB = pC;//pB的动态类型是可以更改的,现在它的动态类型是C*

静态绑定与动态绑定

  • 静态绑定:

绑定的是静态类型,比如函数依赖于对象的静态类型,发生在编译期。

  • 动态绑定:

绑定的是动态类型,比如函数依赖于对象的动态类型,发生在运行期。

示例:

class B
{
    void DoSomething();
    virtual void vfun();
}
class C : public B
{
    void DoSomething();//首先说明一下,这个子类重新定义了父类的no-virtual函数,这是一个不好的设计,会导致名称遮掩;这里只是为了说明动态绑定和静态绑定才这样使用。
    virtual void vfun();
}
class D : public B
{
    void DoSomething();
    virtual void vfun();
}
D* pD = new D();
B* pB = pD;

pD -> DoSomething();//(1)
pB -> DoSomething();//(2)

pD -> vfun();//(3)
pB -> vfun();//(4)
  1. (1) 和 (2) 调用的是不同的函数。

因为DoSomething函数不是虚函数,是静态绑定的,在编译器时期会根据对象的类型选择函数。

pD的静态类型是D*,pB的静态类型是B*。所以(1)调用的是D::DoSomething();(2)调用的是B::DoSmething()。

  1. (3)和(4)调用的是相同的函数。

因为vfun函数是虚函数,是动态绑定的,绑定的是对象的动态类型。

pB虽然和pD的静态类型不同,但是他们指向同一个对象,动态类型是相同的,都是D*。所以调用的都是D::vfun()。

总结:
只有虚函数才有动态绑定,其他的都是静态绑定。

缺省参数与虚函数

虚函数是动态绑定的,缺省参数是静态绑定的。

示例:

class B
{
 virtual void vfun(int i = 10);
}
class D : public B
{
 virtual void vfun(int i = 20);
}
D* pD = new D();
B* pB = pD;

pD->vfun();//a
pB->vfun();//b

a与b 调用的都是D::vfun(),但是缺省参数是自己各自静态类型的。

绝不重新定义继承而来的缺省参数

©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页