深入探索C++对象模型——构造函数语义学

什么时候编译器会合成默认构造函数?

trivial default constructor

当一个类没有任何用户自定义的构造函数时,它所拥有的是编译器声明的一个implicit trivial default constructor,这些构造函数实际上并不会被编译器合成出来。

编译器的需要

在四种情况下,为了满足编译器的需要,编译器会合成一个implicit nontrivial default constructor,以设置好基类,类对象,虚函数表,虚基类的信息。 

(1)类对象有默认构造函数时,编译器会为该类合成一个有用的构造函数,以调用类对象的构造函数,为其设定好初始值;

(2)类的基类有默认构造函数时;

(3)当类中有virtual function或类的基类有virtual function时,由于在编译的时候编译器会为这种类产生一个虚函数表,并且为每一个对象安插一个虚指针以指向虚函数表,因此编译器会合成一个默认构造函数,并在其中正确的设置好虚指针的值。

(4)带有虚基类的class

虚基类的实现方法在不同编译器上区别较大,但是共同点是必须是virtual base class在每一个派生类的位置,能够在执行期准备妥当。虚基指针也是在构造函数内安置妥当。

程序员的需要

对于类的内置类型成员,由编译器合成的构造函数不会去设置初始值,使这些值正确的被初始化,程序员必须提供显示的构造函数来完成。

copy constructor和copy assignment operator

Default Memberwise Initialization(默认的深拷贝)

当一个类没有提供显示的拷贝构造函数时,会以深拷贝的方式初始化每一个类对象。只有当一个类不展现bitwise copy semantics时,编译器才会为之产生拷贝构造函数。

不展现bitwise copy的四种情况与合成nontrivial constructor的情况相同。前两者是为了转调用或类对象或基类的拷贝构造函数,后两个是为了调整vptr和vbtr的值

参数传入,NRV优化

函数参数的初始化

void foo(X x0);//函数的声明
//调用形式
X xx;
foo(xx);
//可能的转化形式
X _tmp;//生成一个临时对象
_tmp.X::X(xx);//拷贝xx对象
foo(_tmp);//void foo(X x0)被改写为void foo(X& x0)

一种参数的初始化行为为产生一个临时对象,并执行copy constructor拷贝参数的值,而后把这个临时对象引用到函数之中,最后被自动析构。

返回值的初始化和NRV优化

X bar()
{
    X xx;
    //处理xx
    return xx;
}
对应的伪代码为
void bar(X& _result)
{
    X xx;
    //处理xx
    _result.X::X(xx);
    return;
}

当编译器支持NRV优化时,会以xx在指定变量上拷贝构造,并直接处理_result

void bar(_result)
{
    _result.X::X(xx);
    //直接处理_result
    return;
}

构造函数初始化列表

class String;
class Word
{
public:
	Word()
	{
		_name = 0;
		_count = 0;
	}
private:
	String _name;
	int _count;
};

Word::Word()
{
	_name.String::String();
	String tmp = String(0);
	_name.String::operator=(tmp);
	tmp.String::~String();
	_cnt = 0;
}
即程序会先构造变量,再拷贝赋值。因此用参数化列表,直接构造的效率会更高。类对象的初始化顺序和初始化列表中的顺序无关,取决于其在类中的声明顺序。
另外,以下情况只能在初始化列中赋值:

(1)初始化一个引用对象;因为引用必须在声明的时候指定绑定的值;

(2)初始化一个const变量,因为const 变量不能修改值;

(3)调用一个base class的constructor,而他有一组参数的时候;

(4)调用member class的constructor,而他有一组参数的时候。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值