Delete 关键字新特性

Delete 关键字新特性

在C ++ 11中,引入了关键字delete的新功能。我们可以将delete关键字应用于限制函数的使用。

下文将演示以下常见的使用场景:

  • 应用于编译器自动生成的函数以禁止使用特定的操作(如复制,比较)
  • 应用在成员函数上防止数据类型转换时导致数据丢失
  • 应用在new运算符上来限制堆上对象的创建
  • 应用在模板类上来限制创建特定的类实例

禁用复制构造函数和赋值运算符

我们可以将delete应用于编译器自动生成的函数,也可以用于其他函数。下面的User类中删除了复制构造函数和赋值运算符,如果有人尝试调用已删除的函数,则它将生成编译时错误。

class User{
	int id;
	string name;
public:
	User(int userId, std::string userName) : id(userId), name(userName){}

	User(const User & obj) = delete;	//禁用复制构造函数
	User & operator = (const User & obj) = delete;	//禁用赋值运算符
};

下面的代码尝试使用赋值运算符,因此引发了编译错误:'User::User(const User &)' : attempting to reference a deleted

int main(){
	User userObj(1, "Driver");
	User obj = userObj;
	return 0;
}

防止自动类型转换造成数据丢失

在上面的例子中,虽然User构造函数接受int作为id的参数类型,但是我们依然可以传入double。编译时不会报错:

User userObj2(2.1, "Double");

使用delete关键字,我们可以防止参数传入时发生的自动类型转换:

User(double userId, std::string userName) = delete;	

在使用delete关键字后,使用double创建User对象会抛出编译时错误:User::User(double,std::string)' : attempting to reference a deleted function

限制动态创建对象

可以将delete 关键字用在new运算符,从而限制动态创建User对象。

class User{
	int id;
	string name;
public:
	User(int userId, std::string userName) : id(userId), name(userName){}
    //禁止使用new运算符在堆上创建对象
	void * operator new (size_t) = delete;
};

new运算符被禁止使用后,以下代码将会产生编译时错误:'void *User::operator new(size_t)' : attempting to reference a deleted function

auto user1 = new User(1, "Driver");

限制模板类创建特定类型的实例

使用delete关键字,我们可以限制模板类或模板函数的某些实例化。让我们看看如何做到这一点,
将上面的User类改造成模板类:

template <typename T>
class User{
	T id;
	string wigth;
public:
	User(T a, T b) : x(a), y(b){}
	User(char a, char b) = delete;
};

现在,假设我们要限制没有人可以使用带有char作为模板参数的User类。为此,我们需要使用通过delete关键字:

User(char a, char b) = delete;

此后,尝试使用char作为模板参数的类将生成编译时错误。'User<std::string>::User(char,char)' : attempting to reference a deleted function

User<string> user2('1', '0');

发布了90 篇原创文章 · 获赞 31 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/BlackCarDriver/article/details/105434598