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

静态类型:对象在声明时采用的类型,在编译期既已确定;
动态类型:通常是指一个指针或引用目前所指对象的类型,是在运行期决定的;
静态绑定:绑定的是静态类型,所对应的函数或属性依赖于对象的静态类型,发生在编译期;
动态绑定:绑定的是动态类型,所对应的函数或属性依赖于对象的动态类型,发生在运行期;

1、

class B{
     
public:
    void vfun(int i=10)
    {
     
        qDebug() << "B:" << i;
    }
};

class D: public B{
     
public:
    void vfun(int i=20)
    {
     
        qDebug() << "D:" << i;
    }
};

int main(int argc, char *argv[])
{
     
    D* pD=new D(); // pD的静态类型是它声明的类型D*,动态类型也是D*
    B* pB=pD;      // pB的静态类型是它声明的类型B*,动态类型是pB所指的对象pD的类型D*
    pD->vfun();    //pD的动、静态类型都是D*,因此调用D::vfun();
    pB->vfun();    //pB的静态类型永远都是B*,不管其指向的是哪个子类,都是直接调用B::vfun();
}

运行结果

D: 20  
B: 10 

2、

class B{
     
public:
    virtual void vfun(int i=10)
    {
     
        qDebug() << "B:" << i;
    }
};

class D: public B{
     

};

int main(int argc, char *argv[])
{
     
    D* pD=new D(); // pD的静态类型是它声明的类型D*,动态类型也是D*
    B* pB=pD;      // pB的静态类型是它声明的类型B*,动态类型是pB所指的对象pD的类型D*
    pD->vfun();    //pD的动、静态类型都是D*,但是D类中没有找到vfun()函数,因此调用基类中的vfun()函数。
    pB->vfun();    //pB的静态类型是B*,因为在B类中vfun()定义的是虚函数virtual。所以要先在子类中寻找,但是子类中没有重新定义,所以调用基类中的B::vfun()函数。
}

运行结果

B: 10 
B: 10 

3、

class B{
     
public:
    virtual void vfun(int i=10)
    {
     
        qDebug() << "B:" << i;
    }
};

class D: public B{
     
    virtual void vfun(int i=20)
    {
     
        qDebug() << "B:" << i;
    }
};

int main(int argc, char *argv[])
{
     
    D* pD=new D(); // pD的静态类型是它声明的类型D*,动态类型也是D*
    B* pB=pD;      // pB的静态类型是它声明的类型B*,动态类型是pB所指的对象pD的类型D*
    pD->vfun();    //pD的动、静态类型都是D*,调用D::vfun()函数
    pB->vfun();    //pB的静态类型是B*,因为在B类中vfun()定义的是虚函数virtual。所以要先在子类中寻找,调用D::vfun()函数
}

运行结果

D: 20
D: 10

注意:此例中pB->vfun()虽然调用的是子类D::vfun()函数,但是缺省参数 i 用的确实基类中 i 的缺省值10。这就造成了逻辑的混乱。

这里只给出建议:
绝对不要重新定义一个继承而来的virtual函数的缺省参数值,因为 缺省参数值都是静态绑定 (为了执行效率),而virtual函数却是动态绑定。

参考:https://www.cnblogs.com/AndyJee/p/4575670.html
https://www.cnblogs.com/lizhenghn/p/3657717.html

你可能感兴趣的:(c++,C++中的静态绑定和动态绑定)