Dynamic and Static binding of C ++

Source: Internet
Author: User

Dynamic binding and static binding are used only to support c ++ polymorphism. Understanding their differences helps to better understand polymorphism and avoid mistakes during programming. Four terms need to be understood:
1. static object type: the type of the object to be declared. It is determined during the compilation period.
2. Dynamic Object type: the type of the object currently referred. It is determined during the runtime.

The dynamic type of the object can be changed, but the static type cannot be changed. For more information about the static and dynamic types of objects, see the following example:

Class B
{
}
Class C: public B
{
}
Class D: public B
{
}
D * pD = new D (); // The static type of pD is its declared type D *, and the dynamic type is also D *
B * pB = pD; // The static type of pB is its declared type B *, and the dynamic type is the type of the object pD pointed to by pB *
C * pC = new C ();
PB = pC; // The dynamic type of pB can be changed, and now its dynamic type is C *
3. Static binding: the static type of the object is bound. A feature (such as a function) depends on the static type of the object and occurs during compilation.

4. dynamic binding: the dynamic type of the object is bound. A feature (such as a function) depends on the dynamic type of the object and occurs at runtime.

Class B
{
Void DoSomething ();
Virtual void vfun ();
}
Class C: public B
{
Void DoSomething (); // first, this subclass redefines the no-virtual function of the parent class. This is a bad design and causes name masking; this is only used to describe dynamic binding and static binding.
Virtual void vfun ();
}
Class D: public B
{
Void DoSomething ();
Virtual void vfun ();
}
D * pD = new D ();
B * pB = pD;
Let's take a look. Do pD> DoSomething () and pB> DoSomething () call the same function?
No, although both pD and pB point to the same object. Because the function DoSomething is a no-virtual function, it is statically bound, that is, the compiler selects the function according to the static type of the object during compilation. If the static type of pD is D *, the compiler points to D: DoSomething () when processing pD-> DoSomething (). Similarly, if the static type of pB is B *, Then pB-> DoSomething () calls B: DoSomething ().
 
Let's take a look. Are pD-> vfun () and pB-> vfun () Calling the same function?
Yes. Because vfun is a virtual function, it is dynamically bound, that is to say, it is bound to the dynamic type of the object. Although pB and pD have different static types, they point to an object at the same time, their dynamic types are the same, all of which are D *. Therefore, they call the same function: D: vfun ().
 
The above are all for object pointers, which are also applicable to reference cases.
 
The dynamic and static types of the pointer and reference may be inconsistent, but the dynamic and static types of the object are consistent.
D;
D. DoSomething () and D. vfun () always call D: DoSomething () and D: vfun ().
 
For those dynamic binding and static binding, I have summarized the following articles:
I summarized one sentence: only virtual functions use dynamic binding, and all others are static binding. At present, I have not found that this sentence is not applicable. If there is an error, I hope you can point it out.
 
Special Notes: www.2cto.com
When the default parameters and virtual functions appear together, the situation is a little complicated and prone to errors. We know that virtual functions are dynamically bound, but the default parameter is static for execution efficiency.

Class B
{
Virtual void vfun (int I = 10 );
}
Class D: public B
{
Virtual void vfun (int I = 20 );
}
D * pD = new D ();
B * pB = pD;
PD-> vfun ();
PB-> vfun ();

The above analysis shows that pD-> vfun () and pB-> vfun () are called Functions D: vfun (), but what are their default parameters?
For analysis, the default parameter is statically bound. When pD-> vfun () is used, the static type of pD is D *, so the default parameter is 20. Similarly, pB-> the default value of vfun () is 10. The code is correct.
No one will like this feature. So always remember:
"Never redefine the inherited default parameter (Never redefine function's inherited default parameters value .)"
 
About c ++
At present, I basically work under the "Object-Oriented Programming" subset of c ++, but I do not know much about more complex knowledge. Even so, there have been a lot of things to pay attention to during programming so far, and it may continue to increase later. This may be the reason why many people oppose c ++.
C ++ is one of Google's four official languages. However, Google has launched the go language in recent years, and its positioning is similar to that of c/c ++. Considering this situation, I think it may be that Google programmers are deeply aware of the complexity of c ++, so they want to develop a c ++ alternative language. You have time to understand the go language and how to choose it when it is similar to c ++.

 

For C ++ dynamic binding, one sentence is that the compiler uses the static analysis method and the virtual function design to achieve dynamic runtime.

The technology that intelligently executes correct virtual functions. Therefore, to thoroughly understand the dynamic binding technology, you only need to master two points: one is the static compilation process of the compiler, and the other is
Basic knowledge of virtual functions. With these two points of understanding, any dynamic binding analysis is easy.

The following is an example of Code Description:


# Include <iostream>
Using namespace std;

Class
...{
Public:
Void fA ()... {cout <"A: fA ()" <endl ;}
Virtual void vfA ()... {cout <"A: vfA ()" <endl ;}
Void emptyB ()... {cout <"A: emptyB ()" <endl ;}
Void vfAonly ()... {cout <"A: vfAonly ()" <endl ;}
};

Class B: public
...{
Public:
Void fB ()... {cout <"B: fB ()" <endl ;}
Virtual void vfA ()... {cout <"B: vfA ()" <endl ;}
Virtual void vfB ()... {cout <"B: vfB ()" <endl ;}
Void emptyA ()... {cout <"B: emptyA ()" <endl ;}
Virtual void vfAonly ()... {cout <"B: vfAonly ()" <endl ;}
};

Int main ()
...{
A * p = new B;
B & r = * (B *) p;

P-> fA (); // 1
// P-> fB (); // 2
P-> vfA (); // 3
// P-> vfB (); // 4
// P-> emptyA (); // 5
P-> emptyB (); // 6
P-> vfAonly (); // 7

Cout <endl;

R. fA (); // 8
R. fB (); // 9
R. vfA (); // 10
R. vfB (); // 11
R. emptyA (); // 12
R. emptyB (); // 13
R. vfAonly (); // 14

Delete p;
Return 0;
}

Output result:

A: fA ()
B: vfA ()
A: emptyB ()
A: vfAonly ()

A: fA ()
B: fB ()
B: vfA ()
B: vfB ()
B: emptyA ()
A: emptyB ()
B: vfAonly ()

 

Analysis:

We simulate the compilation process of the compiler to explain. It only depends on how the compiler compiles the rows called by those functions with labels.

Line 1. In the eyes of the compiler, p is A pure class A pointer and has no connection with the Class B object it points. Therefore, when you see
P-> fA (), the compiler searches for fA in the definition of A, finds it, and generates the call code.
Row 2. If this line is not commented out, the compiler searches for the definition fB in the definition of A, but cannot find this name, and an error message is output.
Row 3: the compiler continues to search for vfA in definition A. This time, the keyword virtual is found. Therefore, the virtual function is used for calling.
Code Generation Technology: Based on the Offset Value of vfA, code is generated to call the function pointed to by this offset value in the virtual function table. In particular
Yes. During static compilation, the compiler only knows the offset value and does not know what function the offset actually points to at runtime. Actual Effect
Yes, because p points to the B object during the runtime, the virtual function vfA () of B is called ().
Row 4. If this line is not commented out, the compiler searches for the name vfB in the definition of A and cannot find it. An error occurs. Remember the first principle, the compiler
It is a static compilation. I don't know if p is related to Class B.
Line 5. Same as 4. The name emptyA cannot be found.
Row 6: simple. Find the name emptyB.
Line 7: simple. Find the name vfAonly.

Row 8. From here, the function is called by Class B referencing r. In the eyes of the compiler, r is A pure B class reference. It does not assume that r and A have any
Link. Therefore, in this line, the compiler goes to class B Definitions to find the name fA. Because B inherits from A, including all the public function definitions of,
The compiler successfully finds A: fA.
Row 9. Similar to row 8, find B's Function Definition fB.
Row 10. Similar to row 3, the compiler generates code to call a function pointed to by a certain offset in the virtual function table. This offset points to B: vfA during running.
Row 11: The Compiler generates code to call a function pointed to by a certain offset in the virtual function table. This offset points to B: vfB during running.
Row 12. Simple. Find the name emptyA.
Row 13: simple. Find the name A: emptyB. Because B inherits from.
Row 14: The Compiler generates code to call a function pointed to by a certain offset in the virtual function table. This offset points to B: vfAonly at runtime. Why does the compiler know?
What is the virtual function vfAonly of B rather than the non-virtual function of? This is related to another static compilation rule, named hidden.
If a function of the same name of the base class exists in the scope of the inherited class, the name of the inherited class hides the function of the same name of the base class.
A: vfAonly.

 


From Slow Dance

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.