C++注解|隐式声明的那些函数。
C++注解
构造函数相关
问题引出
在使用自己定义的类实现某些操作时,可能会出现这样的报错。
error C2280: attempting to reference a deleted function
表示 被引用的函数已被删除的报错
并且表明该函数为拷贝赋值函数。可你发现,你根本就没有定义这个么函数,引用,和被删除的前提就是它之前存在过?那么我们问题就来了。
拷贝赋值函数:Tile &Tile::operator =(const Tile &)
注: Tile 不是模板。
探讨
我们将问题定位在这个拷贝赋值函数上,探讨关于拷贝复制函数是如何出现的
我们都知道,(假设 自定义的名字为Tile)
C++的构造函数有:
- 默认构造函数 (无参)
- 析构函数 (无参)
- 拷贝构造函数
- (const Tile &)return Tile&
- 拷贝赋值函数
- operator= (const Tile &) return Tile&
- operator= ( Tile &) return Tile&
移动构造函数
- ( Tile &&)return Tile&
移动赋值函数
- operator= ( Tile &) return Tile&&
生成这些特殊成员函数(或不生成)的规则比较复杂,每个特殊成员函数有几种不同的状态,对状态进行判断:
- 隐式声明还是用户声明
- 默认提供还是用户提供
- 正常状态还是删除状态
需要知道的原则:
- 隐式声明的必然是默认提供的;
- 默认提供的才可能被删除;
- 用户提供的也必然是用户声明的。
C++默认构造函数是否提供的情况:
如果自定义了一个任意的构造函数,系统将不在提供默认无参构造
如果自定了一个普通构造函数,系统还会提供一个拷贝构造
- 如果自定义了一个拷贝构造.系统将不在提供默认拷贝构造
- 如果自定义一个析构函数,系统将不在提供默认的析构函数
- 没有初始化的非静态 const 数据成员和引用类型数据成员:导致默认提供的默认构造函数被删除。
- 非静态的 const 数据成员和引用类型数据成员:导致默认提供的拷贝构造函数、拷贝赋值函数、移动构造函数和移动赋值函数被删除。
- 用户如果没有自己提供一个拷贝构造函数,编译器会隐式声明一个。
- 用户如果没有自己提供一个拷贝赋值函数,编译器会隐式声明一个。
- 用户如果自己声明了一个移动构造函数或移动赋值函数:则默认提供的拷贝构造函数和拷贝赋值函数被删除。
- 用户如果没有自己声明拷贝构造函数、拷贝赋值函数、移动赋值函数和析构函数:编译器会隐式声明一个移动构造函数。
- 用户如果没有自己声明拷贝构造函数、拷贝赋值函数、移动构造函数和析构函数:编译器会隐式声明一个移动赋值函数。
参考
参考stack overflow 问答帖子
引用其中的回复
The error clearly mentions Tile &Tile::operator =(const Tile &)
, so it’s about the assignment operator, not the move-assignment operator. You need to implement it for Tile
. You’re also missing Tile
‘s copy-constructor.
Quote from here :(这也是从cpprereference中原文)
The implicitly-declared or defaulted copy assignment operator for class T is defined as deleted in any of the following is true:
- T has a non-static data member that is const
- T has a non-static data member of a reference type.
- T has a non-static data member that cannot be copy-assigned (has deleted, inaccessible, or ambiguous copy assignment operator)
- T has direct or virtual base class that cannot be copy-assigned (has deleted, inaccessible, or ambiguous move assignment operator)
- T has a user-declared move constructor
- T has a user-declared move assignment operator