zoukankan      html  css  js  c++  java
  • c++的动态绑定和静态绑定

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

    1、对象的静态类型:对象在声明时采用的类型。是在编译期确定的。

    2、对象的动态类型:目前所指对象的声明。在运行期决定。对象的动态类型可以更改,但是静态类型无法更改。

    关于对象的静态类型和动态类型,看一个示例:

    class A{};
    class B: public A{};
    class C: public A{};
    
    int main()
    {
        C *pc=new C();//pc的静态类型是它声明的类型C*,动态类型也是C*
        A *pa=pc;//pa的静态类型是它声明的类型A*,pa的动态类型所指向的对象pc的类型A*
        B *pb=new B();
        pa=pb;//pa的动态类型是可以更改的,现在它的动态类型是B*
        return 0;
    }

    3、静态绑定:绑定的是对象的静态类型,某特性(比如函数)依赖于对象的静态类型,发生在编译期。

    4、动态绑定:绑定的是对象的动态类型,某特性(比如函数)依赖于对象的动态类型,发生在运行期。

    class A
    {
    public:
        void dosomething()
        {
            cout<<"A"<<endl;
        }
    
        virtual void fun()
        {
            cout<<"virtual A"<<endl;
        }
    };
    class B: public A
    {
    public:
        void dosomething()
        {
            cout<<"B"<<endl;
        }
    
        virtual void fun()
        {
            cout<<"virtual B"<<endl;
        }
    };
    class C: public A
    {
    public:
        void dosomething()
        {
            cout<<"C"<<endl;
        }
    
        virtual void fun()
        {
            cout<<"virtual C"<<endl;
        }
    };
    
    int main()
    {
        C *pc=new C();//pc的静态类型是它声明的类型C*,动态类型也是C*
        pc->dosomething();  // C
        pc->fun();  // virtual C
        A *pa=pc;//pa的静态类型是它声明的类型A*,pa的动态类型所指向的对象pc的类型A*
        pa->dosomething();  // A  ①
        pa->fun();  // virtual C
        B *pb=new B();
        pb->dosomething();  //B
        pb->fun();  // virtual B
        pa=pb;//pa的动态类型是可以更改的,现在它的动态类型是B*
        pa->dosomething();  // A  ②
        pa->fun();  // virtual B
        return 0;
    }

      dosomething()是一个非虚函数,它是静态绑定的,也就是在编译的时候根据对象的静态类型来选择函数,所以,pa、pb、pc调用的都是自己的的dosomething()函数,但对于①中的pa的fun()函数和②中的pa的fun()函数,因为fun()为虚函数,它们绑定的是动态对象,所以①的pa调用的是pc的fun()函数,②的pa调用的是pb的fun()函数。

    需要注意的是:

      当缺省参数和虚函数一起出现的时候情况就有点复杂,因为虚函数是动态绑定的,但是为了执行效率,缺省参数是静态绑定的。

    class A
    {
    public:
        virtual void fun(int i=10)
        {
            cout<<"virtual A "<<i<<endl;
        }
    };
    class B: public A
    {
    public:
        virtual void fun(int i=20)
        {
            cout<<"virtual B "<<i<<endl;
        }
    };
    
    int main()
    {
        B *b=new B();
        A *a=b;
        b->fun();//virtual B 20
        a->fun();//virtual B 10
        return 0;
    } 
    b->fun()、a->fun()调用的都是b的fun()函数,但是缺省函数是静态绑定的,所以a->fun()调用的是a的虚函数fun()里面的缺省值10,b->fun()调用的是b的虚函数fun()里面的缺省值20。
    只有涉及虚函数的地方才存在动态绑定!!!!
    参考博客:https://blog.csdn.net/chgaowei/article/details/6427731
  • 相关阅读:
    JS语言中的JSON.parse()和JSON.stringify()
    Django中 @login_required用法简介
    Django model中的save后的return
    windows下gethostbyname 调用失败
    学习打造自己的DEBUG_NEW
    关于new/delete、malloc/free的内存泄漏检测
    C++连接mysql的两种方式(ADO连接和mysql api连接)
    windows下Redis编译安装
    mysql之字符编码问题
    mysql错误用法insert into where
  • 原文地址:https://www.cnblogs.com/ybf-yyj/p/9445985.html
Copyright © 2011-2022 走看看