C++的类有四类特殊成员函数,它们分别是:默认构造函数、析构函数、拷贝构造函数以及拷贝赋值运算符。

1.类中默认函数

  • 默认构造函数
  • 默认析构函数
  • 默认拷贝构造函数
  • 默认拷贝赋值函数
  • 默认移动构造函数
  • 默认移动赋值函数

2.类中自定义的操作函数

  • operator
  • operator&
  • operator&&
  • operator*
  • operator->
  • operator->*
  • operator new
  • operator delete

[= default] 关键字

C++规定,一个类一旦实现了这些函数的自定义版本,则编译器不会再自动生产默认版本。注意只是不自动生成默认版本,当然还是可手动生成默认版本的。当我们自己定义了待参数的构造函数时,我们最好是声明不带参数的版本以完成无参的变量初始化,此时编译是不会再自动提供默认的无参版本了。我们可以通过使用关键字default来控制默认构造函数的生成,显式地指示编译器生成该函数的默认版本。例如:


class Preson
{
public:
	Preson(int a);
	~Preson();
};

Preson A; // 就会报错 类不存在默认的构造函数


注意:只能出现在默认的构造函数,复制和移动构造函数,复制和移动复制运算符和析构函数中


class Preson
{
public:
	Preson() = default;
	Preson(int a);
	~Preson();
};

Preson A; // ok


[= delete] 关键字

有些时候我们希望限制默认函数的生成。典型的是禁止使用拷贝构造函数,以往的做法是将拷贝构造函数声明为private的并不提供实现,这样当拷贝构造对象时编译不能通过,C++11则使用delete关键字显式指示编译器不生成函数的默认版本。


class Preson
{
public:
	Preson() = default;
	Preson(int a) = delete;
	~Preson();
};

Preson a; // ok
Preson b = new Preson(10); // err 无法引用 Preson::Preson(int a)


注意:C++11 中,delete 关键字可用于任何函数,不仅仅局限于类成员函数


class Preson
{
public:
	Preson() = default;
	Preson(int a) = delete;
	~Preson();

	void sayHello(int a) = delete;
	void sayHello(char a);
	void sayHello(std::string a) = delete;
};

Preson* p = new Preson();
p->sayHello(10); // err
p->sayHello('a'); // ok
p->sayHello("hello"); // err