分析obj文件探索编译器何时生成默认构造函数

前言

提起构造函数,很多人都不陌生,在学习C++的时候,我们经常会听到“默认构造函数”的函数,并一直有一个传统认知,就是说在一个类的定义中,如果程序员没有定义任何构造函数的话,编译器会隐式地生成一个默认的构造函数,并称之为“合成默认构造函数”。那么,如果程序员没有定义任何构造函数,编译器是否会生成一个“合成默认构造函数”呢?我们接下来就来探索一下

前提知识

在C++中,如果要生成一个可执行文件,需要经过编译、链接的步骤,一个.cpp的文件,经过编译,就会生成一个.obj(或者.o)文件,这个文件也叫作目标文件,也就是说,.obj文件是编译的结果文件,而最终生成的可执行文件就是把这些.obj文件链接起来生成的。.obj文件属于二进制文件,不能直接看到里面的内容,但是可以借助一些工具来查看,以Windows平台工具为例,可以利用VS的dumpbin工具来查看

示例

现有以下代码

class MCAC
{
public:
	MCAC() 
	{
		cout << "construction complete" << endl;
	}

};

class MCAX
{
public:

private:
	int m_value;
};
int main()
{
	MCAX m_obj;
    return 0;
}

编译执行该段代码,在传统的认知中,编译器会为MCAX类生成一个“合成默认构造函数”,然而,事实果真如此吗?
让我们借助VS的dumpbin工具生成对应的.txt文件进行搜索 MCAX::MCAX
会发现根本搜索不到,也就是说:编译器根本没有合成该函数出来。
那么,编译器究竟在什么时候才会生成“合成默认构造函数呢”
1.编译器生成“合成默认构造函数”的第一种情况
①如果该类没有任何构造函数
②但包含一个类类型的成员变量

于是,我们在MCAX类中新增一个MCAC类型的成员变量

class MCAX
{
public:

private:
	int m_value;
	MCAC m_obj;
};

编译执行,并通过dumpbin工具生成.txt文件,搜索 MCAX::MCAX
发现
在这里插入图片描述
搜索到了 MCAX::MCAX字样,并且在红线处还发现了 MCAC::MCAC,也就是说调用了MCAC类的构造函数

再增加一个新类MCAY,该类也有默认构造函数

class MCAY
{
public:
	MCAY()
	{
		cout << "construction complete" << endl;
	}

};

同时在MCAX类中新增MCAY类型的成员变量

class MCAX
{
public:

private:
	int m_value;
	MCAC m_obj;
	MCAY m_obj2;
};

编译执行,并利用dumpbin导出.txt文件
在这里插入图片描述
在RELOCATIONS中还看到了MCAX::MCAX先调用了MCAC::MCAC,再调用了MCAY::MCAY
如果我们将这两个成员变量的顺序调转一下,再编译,利用dumpbin工具生成.txt文件再查看,发现:
在这里插入图片描述
这一回MCAX::MCAX是先调用MCAY::MCAY,后调用MCAC::MCAC
与MCAX类中这两个成员变量的定义顺序一致

总结

通过探索,发现有以下情况,编译器会生成“合成默认构造函数”
(1)该类没有任何构造函数但包含一个类类型的构造函数
(2)父类带有默认构造函数且子类没有任何构造函数
(3)一个类含有虚函数且该类没有任何构造函数
(4)一个类带有虚基类且该类没有任何构造函数
(5)在定义成员变量时赋初值,C++11支持这种写法

以上结论,均可以通过分析obj文件来进行观察佐证,在Windows下可以通过dumpbin工具
在这里插入图片描述

进行导出.txt文件分析
导出命令为:

dumpbin /all xx.obj > xx.txt
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值