C + + polymorphic in-depth analysis!

Source: Internet
Author: User

The following analysis is based on VS2010. You'll use g++ analysis later to see how g++ handles polymorphism!

1 //polymorphic_test.cpp: Defines the entry point of the console application. 2 //3 4 /**5 Special Note: implementation of C + + polymorphism, in addition to the base class related functions to declare the virtual keyword, you also need the derived class of the function signature and the base class exactly the same! Two conditions are indispensable, otherwise:6 (1) If the function of the derived class has the same name as the function of the base class, but the parameters are different. At this point, whether or not virtual7 keyword, the function of the base class is hidden (note that it is not confused with overloading). 8 (2) If a function of a derived class has the same name as a function of the base class and the parameters are the same, the base class function has no virtual9 key word. At this point, the function of the base class is hidden (be careful not to confuse the overlay). Ten */ One  A#include"stdafx.h" -#include <iostream> - using namespacestd; the  - classA - { -  Public: +A (): A (0){;} -     voidFoo () {std::cout <<"basemember\t"; } +     Virtual voidVfun () {std::cout <<"basevirtual\t"; } A //Private: at     intA; - }; -  - classD | PublicA - { -  Public: inB (): B (1){;} -     voidFoo () {std::cout <<"derivedmember\t"; } to     voidVfun () {std::cout <<"derivedvirtual\t"; } + //Private: -     intb; the }; *  $ voidTest ()Panax Notoginseng { - A; the b b; +A *pa =NULL; AB *PB =NULL; the  +      while(true){ -PA = &A; $         sizeof(a);sizeof(b);  $&a.a; &b.b; &B.A; -(int) &a.a; (int) &b.b; -         inttt = &b-&A; the         intT = (int) &b-(int) &A;  -Pa->foo ();//a non-virtual function is a compiler binding, and a pointer type is called a member function of that type! So here output BasememberWuyiPa->vfun ();//run-time bindings, invoke the actual type function! Output basevirtual\t the  -PA = &C;  WuPa->foo ();//a non-virtual function is a compiler binding, and a pointer type is called a member function of that type! Because the pointer type is a *, the member function of a is called.  -                       //so the output basemember AboutPa->vfun ();//a run-time binding that invokes a member function of the actual type. So the output derivedvirtual\t $         //return 0; -Std::cout <<Std::endl; -  -  APB = &b; +Pb->foo (); Pb->vfun ();//here output derivedmember\t, derivedvirtual\t. Good understanding.  the  -PB = (b*) &A;  $Pb->foo ();//Note here: The non-virtual function is bound during compilation, the PB type is b*, so the member function of B is called. Output derivedmember\t thePb->vfun ();//The virtual function, called the actual type of the function, now PB points to the &a, so call A's member function, output basevirtual\t the  theStd::cout <<"\ n"<<Std::endl; the     } -  in } the  the int_tmain (intARGC, _tchar*argv[]) About { the test (); the     return 0; the}

Based on debug information, observe the object memory address!

After executing pa=&a:

After pointing to Pa=&b:

The object memory layout is remitted based on the memory address. (not very likely to use Word, the painting is too messy.) I'm sorry! )

Based on this memory layout, we can summarize the following:

1. Derived class objects also have independent copies of the base class's inherited members, not as in the deep C + + object model, "derived classes that inherit from the base class are dependent on the base class object"

2. Each object is allocated on the stack address (no new is used). Objects are from high address to low address assignment, so the A object's starting address is greater than the B object, whereas within the object data members are allocated from the low address to the high address, so the B.A address is higher than the B.B address.

3. If there is a vptr, then vptr is allocated at the very beginning of the object (Vptr is the first member of the object Memory layout).

4. If PTR points to different objects while the program is running. When a virtual function is called, the entry address of the virtual function is found through Vptr+offset. (for example, when PA points to &a, then Pa->vfun () is to find the address of vfun through the vptr of the A object, so it is called a::vfun (); When pa = &PB is executed, PA points to &PB at this point, The Vptr+offset of the B object is then called B::vfun ()).

5. Non-virtual functions, which are binding during compilation, what the actual pointer type is, call the member function of that type regardless of the object that the run time points to. Because the type of PA is a *, Pa->foo () always calls A::foo (), and Pb->foo () always calls B::foo ().

Program Run Result:

C + + polymorphic in-depth analysis!

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.