Tag: Virtual table virtual pointer for C + + virtual function
Virtual functions
A virtual function is virtual
a function that is used to modify. Virtual function is the basis of implementing C + + polymorphism.
Virtual table
Each class creates a table for the virtual functions of its own class to hold virtual function members inside the class.
virtual function Table pointer
Each class initializes the virtual table and the virtual table pointer inside the constructor.
Here's a look at the code:
////Main.cpp//Virtualtable////Created by Alps on 15/4/14.//Copyright (c) 2015 Chen. All rights reserved.//#include <iostream>usingNamespace Std;class base{ Public:Virtual void func() {printf ("base\n"); }Virtual voidHunc () {printf ("hbase\n"); }Private:Virtual void Gunc() {printf ("Base private\n"); }};class Derive: Publicbase{ Public:Virtual void func() {printf ("derive\n"); }};class Derivesecond: Publicbase{ Public:void func() {printf ("second!\n"); }};class Derivethird: PublicBase{};class Deriveforth: Publicbase{ Public:void Gunc() {printf ("Derive forth\n"); }};intMainintargcConst Char* argv[]) {Derive D; Base *PB = &d; Pb->func ();//1 output: DeriveDerivesecond sec; PB = &sec; Pb->func ();//2 output: Derive SecondDerivethird Thi; PB = &thi; Pb->func ();//3 output: BaseDeriveforth forth; PB = &forth;//Pb->gunc (); //4 error return 0;}
In this I have created a base class base and other derived classes.
The first // 1
part, which indicates that although we are declaring a pointer to a base class, but pointing to an instance of a derived class, it is called a function of the derived class.
The second // 2
part, which represents the same as 1, // 2
is simply not a virtual function, overriding the virtual function of the parent class. However, it is still stored in the virtual table of the derived class.
As // 3
you can see in the code, the derived class does not overwrite the virtual function of the parent class, although it points to an instance of the derived class, but calls the method of the parent class, because at the time of inheritance, the subclass also has a virtual table, which contains the virtual function table of the parent class.
Virtual functions that are private in- // 4
house cannot be called directly from outside.
Virtual Table Detailed
First look at the following code: Code Source: Rednaxelafx, programming language chef This person I feel very good, here borrow his code, no commercial, if there is a problem, please contact me to delete.
#include <string>#include <iostream>classObject {intIdentity_hash_; Public: Object (): Identity_hash_ (STD:: Rand ()) {}intIdentityhashcode ()Const{returnIdentity_hash_; }Virtual intHashcode () {returnIdentityhashcode (); }Virtual BOOLEquals (object* RHS) {return This= = RHS; }Virtual STD::stringToString () {return "Object"; }};classMyObject: PublicObject {intDummy_; Public:intHashcode () Override {return 0; }STD::stringToString () Override {return "MyObject"; }};intMain () {Object O1; MyObject O2;STD::cout<< O2. ToString () <<STD:: Endl << O2. Identityhashcode () <<STD:: Endl << O2. Hashcode () <<STD:: Endl;}/ * Object vtable-16 [offset to top] __si_class _type_info-8 [TypeInfo Object]--+0 [...] --+0 [vptr]-+0 [&object::hashcode] +8 [Identity_hash_] +8 [&object::equals ] +12 [(padding)] +16 [&object::tostring] MyObject vtable -16 [offset to top] __si_class_type_info-8 [TypeInfo myobje CT]-+0 [...] --+0 [vptr]-+0 [&myobject::hashcode] +8 [Identity_hash_] +8 [&object::equa LS] +12 [dummy_] +16 [&myobject::tostring]*/
The main thing here is that I think that this virtual table of R-Big is really good-looking. So I borrowed it directly and looked a lot better than the code I wrote on my own (T-t).
First of all, when we study, we can temporarily ignore the content of the virtual table less than 0. Starting from +0, vptr
this virtual table pointer points to the virtual table of the class. It is clear to see that in MyObject
the virtual table where the HashCode 和 ToString
function is already a virtual function of the derived class, the function of the parent class is rewritten.
So these two R-big-picture classes have clearly illustrated the operation of the virtual table virtual function of the class.
Then there is no more violent way to force themselves to control the virtual table. In fact, this is from the time I do a Ali pen test, finish the day I saw the R big has done a detailed explanation, here or quote his code good.
Virtual table and virtual function address
The following code comes from R big hand: Rednaxelafx, programming language chef
#include <iostream>using namespace STD;classanimal{protected:intAge_; AnimalintAge): Age_ (age) {} Public:Virtual voidPrint_age (void) =0;Virtual voidPrint_kind () =0;Virtual voidPrint_status () =0;};classDog: Publicanimal{ Public: Dog (): Animal (2) {} ~dog () {}Virtual voidPrint_age (void) {cout<<"Woof, my age ="<< Age_ << Endl; }Virtual voidPrint_kind () {cout<<"I ' m a Dog"<< Endl; }Virtual voidPrint_status () {cout<<"I ' m barking"<< Endl; }};classCat: Publicanimal{ Public: Cat (): Animal (1) {} ~cat () {}Virtual voidPrint_age (void) {cout<<"Meow, my age ="<< Age_ << Endl; }Virtual voidPrint_kind () {cout<<"I ' m a cat"<< Endl; }Virtual voidPrint_status () {cout<<"I ' m Sleeping"<< Endl; }};voidPrint_random_message (void* something) {cout<<"I ' m Crazy"<< Endl;}intMainvoid) {cat Kitty; Dog puppy; animal* PA = &kitty; intptr_t* cat_vptr = * ((intptr_t**) (&kitty)); intptr_t* dog_vptr = * ((intptr_t**) (&puppy)); intptr_t fake_vtable[] = {dog_vptr[0],//For dog::p rint_agecat_vptr[1],//For cat::p rint_kind(intptr_t) Print_random_message}; * ((intptr_t**) pa) = fake_vtable; Pa->print_age ();//Woof, my age = 1Pa->print_kind ();//I ' m a catPa->print_status ();//I ' m crazy return 0;}
We can see what r is up to!! The lunatic vtable himself forged one, and then put it behind the dummy table pointer! Simply admire. See this code I also understand that the virtual table can do so.
Virtual table address and virtual function address
The address of the virtual function table and the address of the (int*)&classname)
virtual function are (int*)*(int*)(&classname)
actually according to the R big, here int
should be changed to be intptr_t
better, so as to prevent the LP64 model, the function pointer is 8 bytes. And the address gets incomplete.
The relationship between the address of the virtual function table and the virtual function address is similar to: x 和 *x
.
C + + Learning-virtual table, virtual function, virtual function table Pointer Learning notes