关于隐式声明移动赋值运算符中“用户声明”的含义及形式问询
关于C++隐式移动赋值运算符中“用户声明”的解释
首先直接回应你的核心疑问:“用户声明的拷贝赋值运算符”绝对不只是class_name & class_name::operator=(class_name &...)这种形式,咱们一步步拆解清楚:
什么是“用户声明”?
在C++标准的语境里,“用户声明”的函数指的是你在代码中显式写出声明(或定义)的函数——不管你是自己写了函数体,还是用=default要求编译器生成默认实现,甚至用=delete禁用这个函数,只要是你主动在类里/类外声明了这个函数,就算是“用户声明”的,区别于编译器自动隐式生成的版本。
哪些算“用户声明的拷贝赋值运算符”?
拷贝赋值运算符的核心是实现对象拷贝语义的operator=重载,只要是你主动声明的这类重载,都属于“用户声明的拷贝赋值运算符”,常见的包括:
- 最典型的
MyClass& operator=(const MyClass&);(带const左值引用参数) - 你提到的
MyClass& operator=(MyClass&);(非const左值引用参数) - 少见但合法的
MyClass operator=(MyClass);(值传递参数的拷贝赋值) - 甚至是你显式用
=default或=delete声明的版本,比如MyClass& operator=(const MyClass&) = default;
只要存在以上任何一种用户声明的拷贝赋值运算符,编译器就不会为你的类隐式生成移动赋值运算符——哪怕你满足其他几个条件(没有用户声明的拷贝构造、移动构造、析构)。
结合隐式移动赋值的生成条件再梳理
再回头看你提到的规则:只有当类完全没有以下四类用户声明的函数时,编译器才会隐式生成移动赋值运算符:
- 用户声明的拷贝构造函数
- 用户声明的移动构造函数
- 用户声明的拷贝赋值运算符(就是咱们刚才聊的所有情况)
- 用户声明的析构函数
举个简单的例子:
class Test { public: // 这是用户声明的拷贝赋值(用=default) Test& operator=(const Test&) = default; };
哪怕这个类没有其他三个用户声明的函数,编译器也不会隐式生成移动赋值,因为存在用户声明的拷贝赋值运算符。
内容的提问来源于stack exchange,提问作者Moia
相关产品推荐
相关产品推荐

