Memory layout of objects in C++ (1)

In the last article " Poke Me ", I briefly mentioned three categories of inheritance: single inheritance, multiple inheritance, and repeated inheritance.

Generally, if there is no virtual function, the memory layout of the object is as we can see. By defining several variables, the byte size occupied in the memory can be calculated according to the byte alignment. But with a virtual function, it is different, because a virtual function means that there is a virtual function pointer, and we know that the pointer occupies four bytes (32 bits), so start from this article to analyze the existence of virtual functions What is the memory layout of the object? (version is Visual Studio2012)

For single inheritance:


Write the following code:

class Father
{
public:
	Father(int data1):fa(data1){}
	virtual void f(){cout<<"Father::f()"<<" ";}
	virtual void ff(){cout<<"Father::ff()"<<" ";}
	virtual void fff(){cout<<"Father::fff()"<<" ";}
protected:
	int fa;
};

class Son:public Father
{
public:
	Son(int data):sa(data),Father(data){}
	virtual void f(){cout<<"Son::f()"<<" ";}
	virtual void ss(){cout<<"Son::ss()"<<" ";}
	virtual void sss(){cout<<"Son::sss()"<<" ";}
protected:
	int his;
};
class Grandson:public Son
{
public:
	Grandson(int data):ga(data),Son(data){}
	virtual void f(){cout<<"Grandson::f()"<<" ";}
	virtual void ss(){cout<<"Grandson::ss()"<<" ";}
	virtual void ggg(){cout<<"Grandson::ggg()"<<" ";}
protected:
	int ga;
};
typedef void (*Function)(void);//Function pointer
intmain()
{
	//main function mainly prints
	Grandson *pgs=new Grandson(12);
	Function pFun=NULL;//Define a function pointer

	cout<<"[0]   _vfptr"<<endl;
	for(int i=0;i<6;++i)
	{
		pFun=((Function*)(long**)(*(long*)(pgs)))[i];
		cout<<"   "<<"["<<i<<"]"<<" ";
		pFun();
		cout<<((long**)(*(long*)pgs))[i]<<endl;
	}

	cout<<"[1] "<<((long*)pgs)[1]<<endl;
	cout<<"[2] "<<((long*)pgs)[2]<<endl;
	cout<<"[3] "<<((long*)pgs)[3]<<endl;
	
	delete pgs;
	return 0;
}
Note:
(long*)(pgs): convert pgs to long*
(*(long*)(pgs)): dereference, address of virtual function table
(long**)(*(long*)(pgs)): The address of the virtual function table is cast to a second-level pointer

View the memory layout of the object generated by the Grandson class: (click [Project]-”[Properties]-”[C/C++]-”[Command Line]-”Write in the other options

[/d1 reportSingleClassLayout Grandson ]-"Click [OK] just fine)


As can be seen:

1. The subclass inherits the member variables of the parent class, and the member function does not occupy space.

2. When there is a virtual function, a vfptr pointer appears, and the pointer is placed at the beginning of the memory (relative object offset is 0).

3. The function with the same name is overwritten in the virtual table.

4. At the same time, I also saw the existence of a virtual table. The virtual function is stored in the virtual table starting from subscript 0. One problem is that the RTTI information (&Grandson_meta) and vfptr can also be seen from the virtual table. The offset information (0) of the type, but it is not in the position corresponding to the subscript lock 0, where is it? How to print it out? The baby I saw hoped to help me answer.

Print and debug the above program, you can see:


Now, let's draw the memory layout of the Grandson class under single inheritance:


Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326586759&siteId=291194637