当使用对象本身调用复制/移动构造函数时,C++ 中的最佳实践是什么?
例如:
#include <iostream>
using namespace std;
struct Foo{
Foo( const Foo& foo ) { cout << foo.val << std::endl; };
int val;
};
int main()
{
Foo f = Foo(f);
Foo g(g);
Foo h{h};
return 0;
}
这都是合法的 C++,尽管有些编译器会警告你。
通常建议复制赋值运算符检查自赋值。但是自复制构建呢?
T
的复制构造函数创建一个新对象,其值与现有对象(复制构造函数的参数)的值相同。如果将对象传递给它自己的复制构造函数,它还没有有值,因此没有要复制的值。
因此,这可以被视为“不符合契约”地调用复制构造函数,有点像复制构造函数的参数是一个已经被销毁的对象。这不是一个有效的调用,因此您不需要在实现中检查这种情况 - 与自复制分配的情况不同,其中
x = x;
是一个有效的调用,因此您需要确保它有效正确地。
如果用户意外地将对象传递给其自己的构造函数是很常见的,那么在实现中进行纯粹的防御性检查可能是有价值的,但是像
Foo g(g);
这样的代码不太可能被编写。
有人尝试从自身移动构造一个物体的可能性更小。