首页 > 编程笔记

C++ =default和=delete的用法

构造函数、析构函数、拷贝构造函数等是类的特殊成员函数,如果在类中没有显式定义这些成员函数,编译器会提供默认的构造函数、析构函数、拷贝构造函数等。但是,如果在类中显式定义了这些函数,编译器将不会再提供默认的版本。

例如,定义了动物类 Animal,并且在类中显式定义了构造函数,示例代码如下所示:
class Animal
{
public:
    Animal(string name);
private:
    string _name;
};
在上述代码中,定义了有参构造函数,则编译器不再提供默认的构造函数。

如果在程序中需要调用无参构造函数,就需要程序设计者自己定义一个无参构造函数,即使这个无参构造函数体为空,并没有实现任何功能。在实际开发中,一个项目工程中的类非常多,这样做势必会增加代码量。

为了使代码更简洁、高效,C++11 标准引入了一个新特性,在默认函数声明后面添加=default,显式地指示编译器生成该函数的默认版本。

例如,在 Animal 类中,使用“=default”指示编译器提供默认的构造函数,示例代码如下所示:
class Animal
{
public:
    Animal() = default;   //编译器会提供默认的构造函数
    Animal(string name);
private:
    string _name;
};
有时,我们不希望类的某些成员函数在类外被调用,例如,在类外禁止调用类的拷贝构造函数。

在 C++98 标准中,通常的做法是显式声明类的拷贝构造函数,并将其声明为类的私有成员。而 C++11 标准提供了一种更简便的方法,在函数的声明后面加上“=delete”,编译器就会禁止函数在类外调用,这样的函数称为已删除函数。

例如,禁止调用 Animal 类的拷贝构造函数,则可以声明 Animal 类的拷贝构造函数,并使用“=delete”进行修饰,示例代码如下所示:
class Animal
{
public:
    //…
    Animal(const Animal&) = delete;   //在类外禁止调用拷贝构造函数
};
在上述代码中,使用“=delete”修饰拷贝构造函数,则在 Animal 类外就无法再调用拷贝构造函数了。

除了修饰类的成员函数,“=delete”还可以修饰普通函数,被“=delete”修饰的普通函数,在程序中也会被禁止调用。示例代码如下所示:
void func(char ch) = delete;
func('a');   //错误
在上述代码中,func() 函数被“=delete”修饰,当传入字符 'a' 调用 func() 函数时,编译器就会报错,提示“func() 函数是已删除函数”。

优秀文章