只是声明一个空类,不做任何事情的话,编译器会自动为你生成一个默认构造函数、一个默认拷贝构造函数、一个默认重载赋值操作符函数和一个默认析构函数。这些函数只有在第一次被调用时,才会被编译器创建,当然这几个生成的默认函数的实现就是什么都不做。所有这些函数都是 inline 和 public 的。
 我们不希望对象被显示构造(单列模式)或赋值,可以将对应函数声明为private,或者写一个基类,开放部分默认函数,子类去继承就可以了。C++11新增标识符default和delete,控制这些默认函数是否使用。

  • default:被标识的默认函数将使用类的默认行为,如:A() = default;
  • delete:被标识的默认函数将禁用,如:A() = delete;
  • override:被标识的函数需要强制重写基类虚函数;
  • final:被标识的函数禁止重写基类虚函数;

在 C++ 11 中,一个类有八个默认函数:

  1. 默认构造函数;
  2. 默认拷贝构造函数;
  3. 默认析构函数;
  4. 默认重载赋值运算符函数;
  5. 默认重载取址运算符函数;
  6. 默认重载取址运算符const函数;
  7. 默认移动构造函数(C++11);
  8. 默认重载移动赋值操作符函数(C++11)。 ```cpp class A { public:

    // 默认构造函数; A();

    // 默认拷贝构造函数 A(const A&);

    // 默认析构函数 ~A();

    // 默认重载赋值运算符函数 A& operator = (const A&);

    // 默认重载取址运算符函数 A* operator & ();

    // 默认重载取址运算符const函数 const A* operator & () const;

    // 默认移动构造函数 A(A&&);

    // 默认重载移动赋值操作符 A& operator = (const A&&);

};

  1. <a name="UQgEa"></a>
  2. ## 拷贝构造函数
  3. 复制构造函数用于将一个对象复制到新创建的对象中。也就是说,它用于初始化过程中(包括按值传递参数),而不是常规的赋值过程中。类的复制构造函数原型通常如下:
  4. ```cpp
  5. Class_name(const Class_name &);

它接受一个指向类对象的常量引用作为参数。

赋值运算符重载

赋值运算符原型如下:

  1. Class_name & Class_name::operator=(const Class_name &);

取地址操作符重载

  1. const Class_name * operator & () const;

const 修饰的取地址操作符

在成员函数后面加 const,const 修饰 this 指针所指向的对象,也就是保证调用这个 const 成员函数的对象在函数内不会被改变。

移动构造函数和重载移动赋值操作符函数

  1. C++11 新增move语义:源对象资源的控制权全部交给目标对象,可以将原对象移动到新对象, 用于a初始化b后,就将a析构的情况;
  2. 移动构造函数的参数和拷贝构造函数不同,拷贝构造函数的参数是一个左值引用,但是移动构造函数的初值是一个右值引用;
  3. 临时对象即将消亡,并且它里面的资源是需要被再利用的,这个时候就可以使用移动构造。移动构造可以减少不必要的复制,带来性能上的提升。

    左值引用和右值引用

    带右值引用参数的拷贝构造和赋值重载函数,又叫移动构造函数和移动赋值函数,这里的移动指的是把临时量的资源移动给了当前对象,临时对象就不持有资源,为nullptr了,实际上没有进行任何的数据移动,没发生任何的内存开辟和数据拷贝。

参考:
https://zhuanlan.zhihu.com/p/97128024
https://nettee.github.io/posts/2018/Understanding-lvalues-and-rvalues-in-C-and-C/

参考

  1. C++ 的默认函数