【C++11新特性】=default 和 =delete

1.四种特殊的成员函数

C++ 的类有 4 种特殊的成员函数,分别为默认构造函数、析构函数、拷贝构造函数、拷贝赋值运算符。这些类的特殊成员函数负责创建、初始化、销毁、拷贝类的对象。

如果程序员没有显式地为一个类定义某个特殊成员函数,而又需要用到该特殊成员函数时,则编译器会隐式地为这个类生成一个默认的特殊成员函数。

#include <iostream>
using namespace std;

class X
{
private:
	int a;
};

int main()
{
	X x; // 可以编译通过,编译器隐式生成默认构造函数

	return 0;
}

如果在 X 中显式地自定义了非默认构造函数,却没有定义默认构造函数,下面的代码会出现编译错误。

#include <iostream>
using namespace std;

class X
{
private:
    int a;
public:
    X(int i)
    {
        a = i;
    }
};

int main()
{
	X x; // 错误,默认构造函数X::X()不存在

	return 0;
}

为了解决上面的问题,我们需要自定义默认构造函数,如下代码所示。

#include <iostream>
using namespace std;

class X
{
private:
    int a;
public:
    X() {}; // 手动定义默认构造函数
    X(int i)
    {
        a = i;
    }
};

int main()
{
	X x; // 正确,默认构造函数X::X()存在

	return 0;
}

但是手动编写存在两个问题:

  • 程序员工作量变大;
  • 没有编译器自动生成的默认特殊成员函数效率高。

2.=default

为了解决上述的两个问题,C++11 标准引入了一个新特性:=default 函数。

程序员只需在函数声明后加上 =default;,就可将该函数声明为 =default 函数,编译器将为显式声明的 =default 函数自动生成函数体。

#include <iostream>
using namespace std;

class X
{
private:
    int a;
public:
    X() = default; // 该函数比用户自己定义的默认构造函数获得更高的代码效率
    X(int i)
    {
        a = i;
    }
};

int main()
{
	X x; // 正确,默认构造函数X::X()存在

	return 0;
}

=default 函数特性仅适用于类的特殊成员函数,且该特殊成员函数没有默认参数。

class X
{
private:
    int a;
public:
    int f() = default; // 错误,函数f()不是类X的特殊成员函数
    X(int) = default; // 错误,构造函数X(int)不是类X的特殊成员函数
    X(int i = 1) = default; // 错误,默认构造函数X(int i = 1)含有默认参数
    X() = default; // 正确
};

=default 函数既可以在类体内定义,也可以在类体外定义。

class X
{
public:
    X() = default; // 默认构造函数,类体内定义
    X(const X&); // 拷贝构造函数,类体外定义
    X& operator = (const X&); // 拷贝赋值运算符,类体外定义
    ~X() = default; // 析构函数,类体内定义
};

X::X(const X&) = default; // 类体外定义
X& X::operator = (const X&) = default; // 类体外定义

3.=delete

为了能够让程序员显式地禁用某个函数,C++11 标准引入了一个新特性:=delete 函数。

程序员只需在函数声明后加上 =delete;,就可将该函数禁用。

  • 必须在函数第一次声明的时候将其声明为 =delete 函数。

  • 不同于 =default=delete 没有限制为特殊成员函数才能使用 =delete

class X
{
public:
	X();
	X(const X&) = delete;  // 禁用拷贝构造函数
	X& operator = (const X&) = delete; // 禁用拷贝赋值运算符
};

=delete 函数特性还可用于禁用类的某些转换构造函数,从而避免不期望的类型转换。

class X
{
public:
	X(int) = delete;
};

=delete 函数特性还可以用来禁用某些用户自定义的类的 new 操作符,从而避免在自由存储区创建类的对象。

class X
{
public:
	// 禁止使用者在堆上申请对象
	void* operator new(size_t) = delete;
	void* operator new[](size_t) = delete;
};
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值