[C++] 构造函数语义

一、

1.父类带缺省构造函数,子类没有任何构造函数,那因为父类这个缺省的构造函数要被调用,所以编译器会为这个子类合成出一个默认构造函数。

2.合成的目的是为了调用这个父类的构造函数。换句话说,编译器合成了默认的构造函数,并在其中安插代码,调用其父类的缺省构造函数。

二、

如果一个类含有虚函数,但没有任何构造函数时:
因为虚函数的存在,

a)编译器会给我们生成一个基于该类的虚函数表vftable;

b)编译给我们合成了一个构造函数,并且在其中安插代码: 把类的虚函数表地址赋给类对象的虚函数表指针 (赋值语句/代码);

注:

我们可以把 虚函数表指针 看成是我们表面上看不见的一个类的成员函数,为什么这么麻烦,因为虚函数的调用存在一个多态问题,所以需要用到虚函数表指针。

三、
在类中添加代码段:

	virtual void mvirfunc()
	{
		cout << "mvirfunc" << endl;
	}

完整的代码段:

// project100.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "stdafx.h"
#include <iostream>
using namespace std;

class M0TX
{
public:
	M0TX() //默认构造函数
	{
		cout << "wodeceshi" << endl;
	}
};
class MATX
{
public:
	MATX() //默认构造函数
	{
		cout << "goodHAHAHAHA" << endl;
	}
};

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

	//M0TX m0;  //类类型成员变量
	//MATX ma; //类类型成员变量
	void funct()
	{
		cout << "IAmVeryGood" << endl;
	}

	virtual void mvirfunc()
	{
		cout << "mvirfunc" << endl;
	}

	MBTX()//缺省的构造函数
	{
		m_i = 15;
	}
};


int main()
{

	MBTX myb;

	return 1;
}


查看编译器增加的代码:

小结:

编译器给我们往MBTX缺省构造函数中增加了代码:

(a)生成了类MBTX的虚函数表

(b)调用了父类的构造函数

(c)因为虚函数的存在,把类的虚函数表地址赋给对象的虚函数表指针。

注:

1.当我们有自己的默认构造函数时,编译器会根据需要扩充我们自己写的构造函数代码,比如调用父类构造函数,给对象的虚函数表指针赋值。
2.编译器干了很多事,没默认构造函数时必要情况下帮助我们合成默认构造函数,如果我们有默认构造函数,编译器会根据需要扩充默认构造函数里边的代码。

查看汇编代码:

四、

如果一个类带有虚基类,编译器也会为它合成一个默认构造函数。

虚基类:通过两个直接基类继承同一个简介基类。所以一般是三层 ,有爷爷Grand,有两个爹A,A2,有孙子C。

如图:

示例代码:

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

class A : virtual public Grand
{
public:
};

class A2 : virtual public Grand
{
public:
};

class C :public A, public A2 //这里不需要virtual
{
public:
	C()
	{
		int aa;
		aa = 1;
	}
};

查看编译器:

A的构造函数:

A2的构造函数:

C的构造函数:


猜你喜欢

转载自blog.csdn.net/qq_40416052/article/details/84076142