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

    /****************************************************************************
            静态绑定:对象在声明时采用的类型,在编译期既已确定
            动态类型:通常指一个指针或引用目前所指对象的类型,是在运行期决定的
            静态绑定:绑定的是静态类型,所对应的函数或属性依赖于对象的静态类型,
    发生在编译期
            动态绑定:绑定的是动态类型,所对应的函数或属性依赖于对象的动态类型,
    发生在运行期
    
            在C++中,非虚函数一般都是静态绑定,而虚函数都是动态绑定(如此才可实现多态性)
    ****************************************************************************/
    #if 0
    #include <iostream>
    
    class A
    {
    public:
            void func()
            {
                    std::cout<<"A::func()
    ";
            }
    };
    
    class B : public A
    {
    public:
            void func()
            {
                    std::cout<<"B::func()
    ";
            }
    };
    
    class C : public A
    {
    public:
            void func()
            {
                    std::cout<<"C::func()
    ";
            }
    };
    
    int main()
    {
            C* pc = new C();  //pc的静态绑定类型和动态绑定类型均为C*
            B* pb = new B();  //pb的静态绑定和动态绑定类型均为B*
            A* pa = pc;      //pa的静态绑定类型为A*,动态绑定类型为pc的类型C*
    
            pa = pb;          //将pa的动态绑定类型改为B*,其静态绑定类型仍为A*
            C* pNull = NULL;  //pNull静态绑定类型为C*
            
            pa->func();
            pc->func();
            pNull->func();
            
    
            return 0;
    }
    #endif
    /*----------------------------------------------------------------------
    结论:
            1.如果基类A中的func函数不是虚函数,无论哪个指针对func的调用都是
    在定义时的静态类型决定,早在编译期确定了.
            2.同样空指针也能调用非虚函数而不报错,所以要做空指针检查,因此静
    态绑定不能实现多态。
            3.如果基类中的func函数是虚函数,那所有的调用都要等到运行是根据其
    指向对象的类型才能确定,比起静态绑定自然是要有性能损失,但实现了多态。
            4.引用同样适用。
    
    建议:
            绝对不要重新定义继承而来的非虚函数,因为这样导致函数调用由对象声明的
    静态类型确定了,而和对象本身脱离了关系,没有多态,这也将给程序留下预知的
    隐患和莫名奇妙的BUG.
            在动态绑定中,要注意默认参数的使用,当缺省参数和virtual函数一起使用时,
    一定要谨慎。
    -------------------------------------------------------------------------*/
    # include <iostream>
    using namespace std;
    
    class F
    {
    public:
            virtual void func(int i = 1)
            {
                    cout<<"F::func()"<<i<<endl;
            }
    };
    
    class E : public F
    {
    public:
            virtual void func(int i = 0)
            {
                    cout<<"E::func()"<<i<<endl;
            }
    };
    
    void main()
    {
            F* pf = new F();
            E* pe = new E();
    
            pf->func(); //F::func()1
            pf = pe;  //将pf的动态绑定类型改为E*
            pf->func(); //E::func()1
    }
    
    /*----------------------------------------------------------------------------
      注意:
            绝对不要重新定义一个继承而来的virtual函数的缺省参数值,因为缺省参数值都是
    静态绑定的,而virtual函数确实动态绑定.
    -----------------------------------------------------------------------------*/
    
    <wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">
     
     
     
     
  • 相关阅读:
    ZOJ1450 BZOJ1136 BZOJ1137 HDU3932[最小圆覆盖]
    POJ 1755 Triathlon [半平面交 线性规划]
    POJ 3384 Feng Shui [半平面交]
    POJ 3525 Most Distant Point from the Sea [半平面交 二分]
    POJ 1279 Art Gallery [半平面交]
    POJ3335 POJ3130 POJ1474 [半平面交]
    POJ 3608 Bridge Across Islands [旋转卡壳]
    nginx访问量统计
    PV UV QPS 并发数
    PV、UV、IP之间的区别与联系
  • 原文地址:https://www.cnblogs.com/enumhack/p/7473065.html
Copyright © 2011-2022 走看看