Use of C ++ virtual functions

Source: Internet
Author: User

Virtual functions in C ++ (1)

Author: Aber

Although it is difficult to find a C ++ book or magazine that does not discuss polymorphism, most of these discussions make it difficult to use polymorphism and C ++ virtual functions. In this article, I plan to use several methods and examples to help readers understand the virtual function implementation technology in C ++. Note: I want to write this article to share my learning experience with you. I am very knowledgeable and may have some mistakes and shortcomings. I hope you can criticize and correct me. Thank you very much!

I. Basic Concepts
First, C ++ implements polymorphism through virtual functions. "No matter what type of message objects are sent, they send messages in the same form, and the message processing method may change with the objects that take over the message" is called polymorphism. "In the hierarchical structure of a class established on a base class, you can call the process with the same name in the object of any derived class, the processing provided by the called process can change with the class to which it belongs. "A virtual function is a member function that can be redefined in a derived class of this class and assigned another processing function.

Ii. Definition of virtual functions and redefinition in Derived classes

Class class name {public: Virtual member function description;} class name: base class name {public: Virtual member function description ;}

Iii. Structure of virtual functions in memory

1. Let's first look at an example:

#include "iostream.h"#include "string.h"class A {public:virtual void fun0() { cout << "A::fun0" << endl; }};int main(int argc, char* argv[]){A  a;cout << "Size of A = " << sizeof(a) << endl;return 0;}      

The result is as follows: size of a = 4

2. If you add another virtual function: Virtual void fun1 () {cout <"A: Fun" <Endl ;}
Get the same result. If you remove the virtual modifier before the function

class A {public:void fun0() { cout << "A::fun0" << endl; }};int main(int argc, char* argv[]){A  a;cout << "Size of A = " << sizeof(a) << endl;return 0;}      

The result is as follows: size of a = 1
 
3. Check the following results:

class A {public:virtual void fun0() { cout << "A::fun0" << endl; }int a;int b;};int main(int argc, char* argv[]){A  a;cout << "Size of A = " << sizeof(a) << endl;return 0;}      

The result is as follows: size of a = 12

In fact, the structure of the virtual function in the memory is as follows:


Figure 1

In Windows, the pointer occupies 4 bytes in memory, and the virtual function saves the function address in a virtual function table (vtable. Let's look at the example below.

class A {public:virtual void fun0() { cout << "A::fun0" << endl; }virtual void fun1() { cout << "A::fun1" << endl; }int a;int b;};int main(int argc, char* argv[]){A  a;cout << "Size of A = " << sizeof(a) << endl;return 0;}      

The result is as follows:
Size of a = 4

The memory structure of the virtual function is as follows. You can also use the function pointer to first find the virtual function table (vtable), and then access each function address to verify the structure. The author of the foreign website is: "ATL on the hood details" written by zeeshan Amjad"


Figure 2

4. Let's take a look at the memory structure of the inherited virtual function. Let's take a look at the following example.

class A {public:virtual void f() { }};class B {public:virtual void f() { }};class C {public:virtual void f() { }};class Drive : public A, public B, public C {};int main() {Drive d;cout << "Size is = " << sizeof(d) << endl;return 0;}      

The result is as follows: size is = 12. You can see the structure below clearly,


Figure 3

5. Let's take a look at the implementation of polymorphism using virtual functions. Let's take a look at an example:

Class A {public: Virtual void F () {cout <"A: F" <Endl ;}; Class B: Public A {public: Virtual void F () {cout <"B: F" <Endl ;}; Class C: Public A {public: Virtual void F () {cout <"C :: f "<Endl ;}}; class drive: Public c {public: Virtual void F () {cout <" D: F "<Endl ;}}; int main (INT argc, char * argv []) {A; B; C; drive D;. F (); B. F (); C. F (); D. F (); Return 0;} result: a: FB: FC: FD: F

You don't have to explain it. I believe you will understand it at a glance! Note: polymorphism is not a function overload.

6. during the compilation of dynamic connections using virtual functions, the C ++ compiler determines the function that the program uses based on the parameters or return types passed to the function by the program, then the compiler replaces each start with the correct function. This compiler-based replacement is called a static connection, which is executed before the program runs. On the other hand, when the program executes polymorphism, replacement is performed during the program execution period, which is called dynamic connection. Example:

class A{public:virtual void f(){cout << "A::f" << endl;};};class B:public A{public:virtual void f(){cout << "B::f" << endl;};};class C:public A{public:virtual void f(){cout << "C::f" << endl;};};void test(A *a){a->f();};int main(int argc, char* argv[]){     B *b=new B;C *c=new C;char choice;do{cout<<"type  B for class B,C for class C:"<<endl;cin>>choice;if(choice==''b'')test(b);else if(choice==''c'')test(c);}while(1);cout<<endl<<endl;    return 0;}

In the above example, if you remove the virtual modifiers in the class A, B, and C to see the printed results, then let's look at the following example and think about the relationship between the two. What if the virtual modifier in B and C is removed? The result is the same as that in C.

7. Call the function of the inherited class in the base class (if this function is a virtual function) or take an example first:

class A {public:    virtual void fun() {        cout << "A::fun" << endl;    }    void show() {        fun();    }};class B : public A {public:    virtual void fun() {        cout << "B::fun" << endl;    }};int main() {    A a;    a.show();    return 0;}      

Printed result: a: Fun

In the example in section 6, test (A * A) actually has a process of implicit conversion from an inherited class pointer to a base class pointer. We can see that using the virtual function, we can call the inheritance class function in the base class. If it is not a virtual function, the inherited class pointer can only call the base class function after being converted to the base class pointer. Conversely, if the base class pointer is converted to the inherited class pointer, it can only display the conversion. After the conversion, the inherited class pointer can call the base class and the inherited class pointer. Example:

Class A {public: void fun () {cout <"A: Fun" <Endl ;}}; Class B: Public A {public: void fun () {cout <"B: Fun" <Endl;} void fun0 () {cout <"B: fun0" <Endl ;}; int main () {A * A = new A; B * B = new B; A * pA; B * pb; Pb = static_cast <B *> (); // The base class pointer is displayed as the inherited class pointer and converted to Pb-> fun0 (); Pb-> fun (); Return 0;

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.