编译器合成默认构造函数情况分析

目录

情形说明:

情况一:A类中调用了B类构造函数,若A类无构造函数,则默认合成

情形二:父类带缺省构造函数,子类无构造函数

情形三:类中存在虚函数

情形四:类中带有虚基类


 

情形说明:

传统观念之下,如果我们没有自己定义构造函数,那么系统就会默认分配一个隐式的构造函数,但是这是不正确的。编译器比我们想的要更聪明一些,因为只有在此类必须要用构造函数时,才会隐式定义一个默认的构造函数。我们程这种构造函数为“合成的默认构造函数”。

那什么是必要情形的构造函数呢?以下就说明了必要情形。

 

情况一:A类中调用了B类构造函数,若A类无构造函数,则默认合成

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

class MBTX
{
public:
	int m_i;
	int m_j;

	M0TX m0;  //类类型成员变量
	MATX ma; //类类型成员变量
	

	void funct()
	{
		cout << "IAmVeryGood" << endl;
	}
};

int main(){
	MBTX myb; 
}

在上面代码中定义了MBTX类的对象,而MBTX类中又定义了MATX和M0TX的对象,而MATX和M0TX类中都有构造函数,那么想要调用这两个类的构造函数,必须自己要有构造函数,那么系统就会生成默认的构造函数,用来对M0TX和MATX类的构造函数做支撑。

其合成的目的是为了调用M0TX和MATX里的默认构造函数。换句话说:编译器合成了默认的MBTX构造函数,并且在其中安插代码,调用MATX的缺省构造函数。

其中:调用M0TX和MATX构造函数的顺序是由MBTX里定义M0TX和MATX对象的顺序决定的。

 

情形二:父类带缺省构造函数,子类无构造函数

class C
{
public:
	C()
	{
		int aa;
		aa = 1;
	}
};

class A :public C{
    
}

int main(){
    A aa;
    return 1;
}

父类带有无参构造函数,子类没有任何构造函数,那因为父类这个缺省的构造函数要被调用,所以编译器会为这个子类合成出一个默认构造函数。合成的目的是为了调用这个父类的构造函数。换句话说,编译器合成了默认的构造函数,并在其中安插代码,调用其父类的缺省构造函数。

 

情形三:类中存在虚函数

class A{
    int m_i;
    void func1()
    {
        cout << "IAmVeryGood" << endl;
    }

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

int main()
{
    A aa;
    return 1;
}

编译给我们合成了一个构造函数,并且在其中安插代码: 把类的虚函数表地址赋给类对象的虚函数表指针 (赋值语句/代码);生成了类MBTX的虚函数表。当我们有自己的默认构造函数时,编译器会根据需要扩充我们自己写的构造函数代码,比如调用父类构造函数,给对象的虚函数表指针赋值。编译器干了很多事,没默认构造函数时必要情况下帮助我们合成默认构造函数,如果我们有默认构造函数,编译器会根据需要扩充默认构造函数里边的代码。

 

情形四:类中带有虚基类

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;
	}
};

int main(){
    C cc;
    return 1;
}

通过两个直接基类继承同一个基类。所以一般是三层 ,有爷爷Grand,有两个爹A,A2,有孙子C。虚基类结构,编译器为子类和父类都产生了“合成的默认构造函数”。

两个父亲和儿子都有构造函数,其中虚基类结构中,构造函数具有虚基类表(vbtable)。

Q:为什么虚基类(两父类)中要合成默认构造函数?

A:

Q2:为什么要合成虚基类表,虚基类表中含有什么内容?

A2:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值