Overview of static bindings and dynamic bindings for C + +

Source: Internet
Author: User
Tags inheritance

C + + in object-oriented programming, there are static binding and dynamic binding definition, this section is mainly about these two points of distinction.

I am analyzing the inheritance system of a class, so the object described below generally refers to an instance of a class.

First we need to define a few terms:

Static type: The type used by the object at the time of Declaration, which has been determined at compile time;

Dynamic type: Usually refers to a pointer or refers to the type of object currently referred to, is in the run-time decision;

Static binding: The binding is a static type, and the corresponding function or property depends on the static type of the object, which occurs at compile time;

Dynamic binding: The binding is a dynamic type, and the corresponding function or attribute depends on the dynamic type of the object, occurring in the runtime;

As can be seen from the above definition, non-virtual functions are generally statically bound, while virtual functions are dynamically bound (so that polymorphism can be implemented).

First look at the code and run the results:

Class A
{public
:
    /*virtual*/void func () {std::cout << "a::func () \ n";}
};
Class B:public A
{public
:
    void func () {std::cout << "b::func () \ n";}
};
Class C:public A
{public
:
    void func () {std::cout << "c::func () \ n";}
};

The following step-by-step analysis of test code and results,

1 c* pc = new C (); The static type of PC is the type c* it declares, and the dynamic type is also c*;

2 b* PB = new B (); The static type and dynamic type of PB are also b*;

More Wonderful content: http://www.bianceng.cnhttp://www.bianceng.cn/Programming/cplus/

3 * pa = PC; The static type of PA is its declared type A *, and the dynamic type is the type c* of the object pc to which the PA points;

4 Pa = PB; The dynamic type of PA can be changed, and now its dynamic type is b*, but its static type is still a * at the time of Declaration;

5 C *pnull = NULL; The static type of the Pnull is the type c* it declares, and there is no dynamic type because it points to null;

If you understand the meaning of the above code, please continue,

1 Pa->func (); The static type of A::func () PA is always a *, regardless of which subclass it refers to, is called directly a::func ();

2 Pc->func (); The dynamic and static types of the C::func () PC are all c*, so call C::func ();

3 Pnull->func (); C::func () Don't wonder why null pointers can also call functions, because this is OK at compile time, and it doesn't matter if the pointer is empty;

If you comment out the definition of the Func function in Class C, the other invariant, that is,

Class C:public A
{
};
    
Pa->func ();      A::func () the reasons above;
Pc->func ();      The A::func () PC could not find the definition of Func in Class C, so look for it in its base class;
Pnull->func ();   A::func () Reasons have also been explained;

If you add the virtual attribute to the void Func () function in a, the other invariant, that is,

Class A
{public
:
    virtual void func () {std::cout << "a::func () \ n";}
};
    
Pa->func ();      B::func () Because of the virtual function, the PA's dynamic type points to b*, so first find in B, and then call it directly;
Pc->func ();      The dynamic and static types of the C::func () PC are c*, so it is also first found in C;
Pnull->func ();   Null pointer exception, because is Func is a virtual function, so the call to Func can only wait until the runtime to determine, and then found that pnull is a null pointer;

Analysis:

In the example above,

1. If the func in the base class A is not a virtual function, then regardless of PA, Pb, PC point to which subclass object, the call to Func is in the definition of PA, Pb, PC static type decision, already in the compile time determined.

The same null pointer can also call the No-virtual function directly without an error (this also indicates that you must short the pointer check!) ), so static binding cannot implement polymorphism;

2. If the Func is a virtual function, then all calls should wait until the runtime according to the type of the object to determine, compared to static binding nature is to have performance loss, but can achieve polymorphic characteristics;

The code in this article is analyzed for pointers, but it is also true for references.

Here's a summary of the differences between static and dynamic binding:

1. Static binding occurs at compile time and dynamic binding occurs at runtime;

2. The dynamic type of the object can be changed, but the static type cannot be changed;

3. Dynamic binding must be used to achieve dynamic;

4. In the inheritance system, only virtual functions use dynamic binding, and all others are statically bound;

Suggestions:

Never redefine an inherited non-virtual (non-virtual) function (clause 36 of the effective C + + third edition), because this causes the function call to be determined by the static type declared by the object, and the object itself is detached from the relationship, without polymorphism, Also this will leave the program with unpredictable hidden dangers and inexplicable bugs;

In addition, in dynamic binding, also in virtual functions, be aware of the use of default parameters. Be cautious when using both the default and virtual functions, or the problem is difficult to troubleshoot.

Look at the following code:

Class E
{public
:
    virtual void func (int i = 0)
    { 
        std::cout << "e::func () \ t" << I << "\ n";
    }
;
Class F:public E
{public
:
    virtual void func (int i = 1)
    {
        std::cout << "f::func () \ t" <& Lt I << "\ n";
    }
};
    
void Test2 ()
{
    f* pf = new F ();
    e* pe = PF;
    Pf->func (); F::func () 1  Normal, that's it;
    Pe->func ();//f::func () 0  Wow, what's the situation, the function of the subclass is called, but the default value of the parameter in the base class is used!
}

Why this is the case, please see "effective C + + Third Edition" clause 37.

Here is only a suggestion:

Never redefine the default parameter values of an inherited virtual function, because the default parameter values are statically bound (for efficiency), but the virtual function is dynamically bound.

Author: Lizhenghn (lizhenghn@gmail.com)

Source: Http://www.cnblogs.com/lizhenghn

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.