栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

分析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
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/297030.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号