(C++ Object Model): Constructor Semantics (Part 2)

table of Contents

Constructor semantics

①The parent class has a default constructor, and the child class does not have any constructor

② If a class contains virtual functions, but no constructor

③ If a class has a virtual base class, the compiler will also synthesize a default constructor for it

Disassemble to see what code the compiler added


Constructor semantics

①The parent class has a default constructor, and the child class does not have any constructor

  • Because the default constructor of the parent class needs to be called, the compiler will synthesize a default constructor for this subclass.
  • The purpose of synthesis is to call the constructor of this parent class.
  • In other words, the compiler synthesizes the default constructor, inserts code in it, and calls the default constructor of its parent class .
#include <iostream>
using namespace std;

class MBTXPARENT
{
public:
	MBTXPARENT()
	{
		cout << "MBTXPARENT()" << endl;
	}
};

class MBTX :public MBTXPARENT
{
public:
	int m_i;
	int m_j;
	
	void funct()
	{
		cout << "IAmVeryGood" << endl;
	}
};

int main()
{
	MBTX myb;
	return 1;
}
  • Output result:

  • Use dumpbin for testing

② If a class contains virtual functions, but no constructor

  • Because of the existence of virtual functions :
    • a) The  compiler will generate a virtual function table vftable based on this class for us
    • b)  Compiler synthesizes a constructor for us, and inserts the code in it :
      • Assign the virtual function table address of the class to the virtual function table pointer of the class object (assignment statement/code)
      • We can regard the virtual function table pointer as a member function of a class that we can't see on the surface
      • Why is it so troublesome, because there is a polymorphic problem in the call of virtual function, so the virtual function table pointer needs to be used .
#include <iostream>
using namespace std;

class MBTX
{
public:
	int m_i;
	int m_j;
	
	void funct()
	{
		cout << "IAmVeryGood" << endl;
	}
	virtual void mvirfunc()
	{
		cout << "mvirfunc" << endl;
	}
};

int main()
{
	MBTX myb;
	return 1;
}
  • Use dumpbin for testing

  •  Implement the default constructor yourself
class MBTX
{
public:
	int m_i;
	int m_j;
	
	void funct()
	{
		cout << "IAmVeryGood" << endl;
	}
	virtual void mvirfunc()
	{
		cout << "mvirfunc" << endl;
	}
	MBTX()
	{
		m_i = 15;
	}
};
  • The compiler added code to the MBTX default constructor :
    • (A) A virtual function table of the class MBTX is generated
    • (B) The constructor of the parent class is called
    • (C) Because of the existence of virtual functions, assign the virtual function table address of the class to the virtual function table pointer of the object.
  • When we have our own default constructor, the compiler will expand our own constructor code as needed , such as calling the parent class constructor and assigning a pointer to the object's virtual function table.
  • The compiler does a lot of things. It helps us synthesize the default constructor when necessary when there is no default constructor. If we have a default constructor, the compiler will expand the code in the default constructor as needed.

③ If a class has a virtual base class, the compiler will also synthesize a default constructor for it

  • Virtual base class: inherit the same profile base class through two direct base classes. So it is usually three floors, with grandpa Grand, two fathers A, A2, and grandson C

#include <iostream>
using namespace std;

class Grand //爷爷类
{
public:
};

class A : virtual public Grand
{
public:
};

class A2 : virtual public Grand
{
public:
};

class C :public A, public A2 //这里不需要virtual
{
public:
	
};


int main()
{
	C cc;
	return 1;
}
  • Use dumpbin for testing

  • vbtable virtual base class table vftalble (virtual function table)

  • Virtual base class structure, the compiler generates a "synthetic default constructor " for both the subclass and the parent class
     

Disassemble to see what code the compiler added

  • F9 to insert a breakpoint, F5 to run, and then click Debug -> Window -> Disassembly

  • Disassembly code:

Guess you like

Origin blog.csdn.net/baidu_41388533/article/details/108650173