C++11 中增加 default 关键字,本篇文章讲解下空实现的默认构造函数和 default 的默认构造函数的区别。
接下来,从以下几个方面来讲解 default 关键字:
- default 关键字使用示例
- default 和默认构造函数
以下代码运行环境为:win10 专业版 + vs2019 社区版。
- 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; 错误
};
- 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 来代替一个具有空实现的构造函数会带来更好的效率。
至此,本文章内容结束,希望对你有所帮助!