c++中静态绑定和动态绑定

动态绑定和静态绑定是为了支持类中的多态。静态和动态分别对应着编译期和运行期。

静态对象:是在编译期就确定了类型,不能改变。
动态对象:在运行期间确定的类型,可以改变其类型。
静态绑定:绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。
动态绑定:绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期

class base{
public:
    void fun(){
        cout<<"base do something"<<endl;
    }
    virtual void virfun(){
        cout<<"virtual base do something"<<endl;
    }
};
class Derived:public base{
public:
    void fun(){
        cout<<"derived do something"<<endl;
    }
    virtual void virfun(){
        cout<<"virtual derived do something"<<endl;
    }
};
int main()
{
    Derived *son=new Derived();//son的静态类型是它声明的类型Derived*,动态类型也是Derived*
    base *father=son;//father的静态类型是它声明的类型base*,动态类型是father指向对象son的类型Derived*

    son->fun();//输出:son do something
    father->fun();//输出:father do something

    son->virfun();//输出:virtual derived do something
    father->virfun();//输出:virtual derived do something
}

  从上面的例子可以看出,由于fun函数是非virtual函数,所以也就是编译器会在编译期根据对象的静态类型来选择该函数,比如son的静态类型为Derived,而father的静态类型为base。
  而virfun()函数是vitual虚函数,所以在运行期间根据对象的动态类型决定。

注意

虚函数是动态绑定的,但是参数是静态绑定的,这是出于运行时效率的考虑,如果要动态绑定默认参数,则需要一种类似虚函数表的动态机制。 所以你需要记住默认参数的静态绑定的,否则会引起困惑。来看例子吧:

class Shape{
public:
    virtual void draw(int top = 1){
        cout<<top<<endl;
    }
};
class Rect: public Shape{
public:
    virtual void draw(int top = 2){
        cout<<top<<endl;
    }
};
Rect* rp = new Rect;
Shape* sp = rp;
sp->draw();//输出:2
rp->draw();//输出:1

默认参数的值只和静态类型有关,是静态绑定的。

参考:effective c++ item36、item37

发布了5 篇原创文章 · 获赞 0 · 访问量 38

猜你喜欢

转载自blog.csdn.net/m0_38102073/article/details/104539773