我想创建像:
这样的函数void func(sample &a){
sample b();
std::swap(b,a);
}
问题是,当我使用swap时总是使用复制构造函数,并且析构函数应用于交换函数中使用的临时对象。
是否有可能实现非复制交换?
答案 0 :(得分:2)
解决问题的C ++ 11解决方案是在sample
类中提供移动构造函数和移动赋值运算符。然后,std::swap
将使用移动而不是复制操作,这应该更有效(你仍然会看到析构函数被调用,但这通常是在一个“空”对象上,应该非常便宜)。 / p>
通常,如果您正在编写自己的复制构造函数和复制赋值运算符,那么您还需要编写移动构造函数并移动赋值运算符(当然还有析构函数) - 这就是“5的规则”在C ++ 11中,它扩展了C ++ 98中已知的“3规则”。例如,考虑手动管理内存的这个(坏)示例类(N.B.这只是展示的一个例子,在现实生活中使用std::vector
或std::unique_ptr
而不是这样做):
class example {
public:
example()
: ptr{new int[1024]}
{}
example(const example& other)
: ptr{new int[1024]}
{
// Copy other's member array
std::copy(other.ptr, other.ptr + 1024, ptr);
}
example& operator=(const example& other)
{
if (this != &other) {
std::copy(other.ptr, other.ptr + 1024, ptr);
}
return *this;
}
~example()
{
delete[](ptr);
}
example(example&& other)
: ptr(other.ptr) // "steal" other's ptr
{
other.ptr = nullptr;
}
example& operator=(example&& other)
{
std::swap(ptr, other.ptr);
return *this;
}
private:
int* ptr;
};
现在,当你std::swap
两个example
时,交换函数将使用移动操作,不会发生额外的分配,只有一些(便宜的)指针交换,以及一个无操作调用delete[](nullptr)
。
答案 1 :(得分:-1)
您的函数将a
与默认构造的对象交换。如果这是预期的语义,那就
a = sample();
并根据需要提供移动构造函数和赋值。