51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

C++11 default 和默认构造函数

C++11 中增加 default 关键字,本篇文章讲解下空实现的默认构造函数和 default 的默认构造函数的区别。

接下来,从以下几个方面来讲解 default 关键字:

  1. default 关键字使用示例
  2. default 和默认构造函数

以下代码运行环境为:win10 专业版 + vs2019 社区版。

  1. default 关键字使用示例 {#title-0}

请看下面的示例代码:

class Demo
{
public:
	Demo() = default;
	Demo(const Demo&) = default;
	Demo(Demo&&) = default;

	~Demo() = default;

	Demo& operator=(const Demo&) = default;
	Demo& operator=(Demo&&) = default;

	// 以下场景不能使用 default
	// 1.有参非拷贝构造构造函数
	// Demo(int) = default; 错误

	// 2.普通成员函数
	// void show() = default; 错误
};
  1. default 和默认构造函数 {#title-1}

当类的内部存在有参构造函数,此时,如果我们需要使用无参构造函数,就必须手动为类添加该构造函数。

添加无参构造函数的方式有两种,如下代码所示:

class Demo
{
public:
	// 第一种方式
	Demo() {}

	// 第二种方式
	Demo() = default;
};

注意:两种形式的无参构造函数不能共存,此处仅为展示两种方式。

那么,这两种方式有什么区别呢?

第一种方式:当我们使用无参构造函数创建 Demo 类型对象时,由于无参构造函数显式存在,所以,必然会调用该无参构造函数。

请看下面的示例代码:

class Demo
{
public:
	Demo() {}
};

void test()
{
	Demo demo;
}

第 9 行代码对应的汇编代码如下:

Demo demo;
lea         ecx,[demo]  
call        Demo::Demo 

虽然我们知道在第 9 行代码处调用一个空实现的无参构造函数除了增加开销,没有什么用途。但是,通过第 3 行汇编代码,我们看到此处仍然调用了 Demo 的构造函数。

第二种方式:当我们使用无参构造函数创建 Demo 类型对象时,由于使用 default 关键字,那么,无参构造函数是否显式添加就要取决于编译器是否需要。如果需要,则编译器会给我们增加一个无参构造函数,并进行调用。如果不需要,则不会添加无参构造函数。

请看下面的示例代码:

class Demo
{
public:
	Demo() = default;
};

void test()
{
	Demo demo;
}

此时,第 9 行代码并没有调用任何的构造函数。

但是,当 Demo 类内部包含对象成员,并且对象成员包含默认构造函数时,编译器认为有必要调用 Demo 的无参构造函数,此时才会调用 Demo 的无参构造函数。请看下面的示例代码:

class Box
{
public:
	Box() {}
};

class Demo
{
public:
	Demo() = default;
public:
	Box box;
};

void test()
{
	Demo demo;
}

第 17 行创建 demo 对象对应的汇编代码如下:

Demo demo;
lea         ecx,[demo]  
call        Demo::Demo 

从汇编代码来看,确实调用了 Demo 的无参构造函数。

为什么编译器认为有必要调用构造函数?以及哪些场景下会调用无参构造函数,请看文章:http://mengbaoliang.cn/?p=905

由此,我们得知,大部分场景下,可以使用 default 来代替一个具有空实现的构造函数会带来更好的效率。

至此,本文章内容结束,希望对你有所帮助!

赞(3)
未经允许不得转载:工具盒子 » C++11 default 和默认构造函数