C++默认函数

在目标函数后面声明“=default”表示该函数为默认函数。默认函数让我们得以明确指示编译器按“默认”的方式生成目标函数,前提是一个函数可由编译器自动产生,如:默认构造函数、析构函数、拷贝构造函数、移动构造函数、复制赋值操作符和移动赋值操作符等。

使用默认函数的原因有如下几点:

1.改变函数访问限制。按默认方式,编译器只会产生公有“public”函数,若想声明为保护或私有类型则必须手动实现。

2.充当说明注释。若编译器生成的函数即可满足所需,则声明为默认使得函数的意图清晰明了。

3.令编译器生成默认函数。一般来说,仅当用户没有声明自定义构造函数时,编译器才会生成默认构造函数,针对这种情况,添加“=default”可明确指示编译器生成默认函数。

4.令析构函数成为虚函数,托付给编译器生成。

5.强制拷贝构造函数只接收特定形式参数。如:使之不接受const引用,而改为接收源对象的非const引用。

6.编译器产生的函数具备某些特殊性质,可以利用默认生成函数的特殊性质。

以下是上述应用的例子:

class Y
{
private:
	Y() = default;						//改变访问级别为public
public:
	Y(Y&) = default;					//接收非const引用
	Y& operator=(const Y&) = default;	//充当注解
protected:
	virtual ~Y() = default;				//改变访问级别为public,并加入虚函数性质
};

默认函数的特点1:

上面提到,编译器产生的函数具备特殊性质,与自定义函数最大的差异是编译器有可能生成平实函数,当类作为一个整体满足一定要求(详见C++官方文件ISO/IEC 14882:2011),相关成员函数才会成为平实函数,其特点如下:

平实函数(trival function),实际意义是默认构造函数和析构函数不执行任何操作;复制、赋值和移动操作仅仅涉及最简单、直接按位进行内存的复制/转移操作,没有其它任何行为;若对象所含默认函数全是平实函数,则可按照POD(Plain Old Data)方式进行处理。

1.如果某对象的拷贝构造函数、拷贝赋值操作符和析构函数都是平实函数,那么它就可以通过memcpy()或memmove()复制

2.constexpr函数所用的字面值型别(literal type)必须具备平实的构造函数、拷贝构造函数和析构函数。

3.若要允许一个类被联合体(union)包含,若联合体已经具备自定义构造和析构函数,则这个类必须具有平实的构造函数,拷贝构造函数,复制操作符和析构函数。

4. 若某个类充当了类模版std::atomic<>的模版参数,则他应该带有平实的拷贝赋值操作符才能提供该类型的原子操作

默认函数的特点2:

如果用户没有为某个类提供构造函数,那么它便得以充当聚合体,其初始化过程可依照聚合体表达式完成:

聚合体(aggregate),是C++11引入的概念,通常可以是数组、联合体、结构体或类(不得含有虚函数或自定义构造函数,也不得继承父类的构造函数)。

struct aggregrate
{
	aggregrate() = default;
	aggregrate(const aggregrate&) = default;
	int a;
	double b;
};
aggregrate x = { 42, 3.141 };//x.a = 42; x.b=3.141

默认函数的特点3:

假定某个类的默认构造函数由编译器自动生成,其每个数据成员与全部基类同样如此,且成员都属于内建型别。那么在初始化这个类的实例时,在该实例没有静态生存期的情况下,是否显式调用默认构造函数,会影响数据成员的初始化:不显式调用则数据成员的值未确定,读取会引起未定义行为;显式调用则数据成员初始化为0

静态生存期(static storage duration),指某些对象随整个程序开始而获得存储空间,到程序结束空间才被回收,这些对象包括静态局部变量、静态数据成员、全局变量等。

struct X
{
	int a;
};
X x1;		//x1.a尚未确定
X x2 = X(); //x2.a==0成立

若实例存在静态生存期,则默认构造函数的类的数据成员会被初始化为0。

原子类型正是应用了这一性质,将自身的构造函数显式声明为“默认”。除去以下情形,原子类型的初始值是未定义:具有静态生存期;显式调用默认构造函数,进行零值初始化;明确设定了初始值。各种原子类型均具备一个构造函数,单独接受一个参数作为初始值,它们都被声明为constexpr函数,以准许发生静态初始化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值