实现非复制交换功能
achieve non copying swap function
我想创建如下函数:
void func(sample &a){
sample b();
std::swap(b,a);
}
问题是,当我使用 swap 时,总是使用复制构造函数,并将析构函数应用于 swap 函数中使用的临时对象。
是否可以实现非复制交换?
您的函数将 a
与默认构造的对象交换。如果这是预期的语义就做
a = sample();
并提供您认为合适的移动构造函数和赋值。
您的问题的 C++11 解决方案是在您的 sample
class 中提供移动构造函数和移动赋值运算符。然后,std::swap
将使用移动而不是复制操作,这应该更有效(您仍然会看到正在调用析构函数,但这通常是在 "empty" 对象上并且应该非常便宜) .
通常,如果您要编写自己的复制构造函数和复制赋值运算符,那么您还需要编写移动构造函数和移动赋值运算符(当然还有析构函数)——这就是 "rule of 5" 在 C++11 中,它扩展了 C++98 中已知的 "rule of 3"。例如,考虑这个(坏的)示例 class,它手动管理内存(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)
.
我想创建如下函数:
void func(sample &a){
sample b();
std::swap(b,a);
}
问题是,当我使用 swap 时,总是使用复制构造函数,并将析构函数应用于 swap 函数中使用的临时对象。
是否可以实现非复制交换?
您的函数将 a
与默认构造的对象交换。如果这是预期的语义就做
a = sample();
并提供您认为合适的移动构造函数和赋值。
您的问题的 C++11 解决方案是在您的 sample
class 中提供移动构造函数和移动赋值运算符。然后,std::swap
将使用移动而不是复制操作,这应该更有效(您仍然会看到正在调用析构函数,但这通常是在 "empty" 对象上并且应该非常便宜) .
通常,如果您要编写自己的复制构造函数和复制赋值运算符,那么您还需要编写移动构造函数和移动赋值运算符(当然还有析构函数)——这就是 "rule of 5" 在 C++11 中,它扩展了 C++98 中已知的 "rule of 3"。例如,考虑这个(坏的)示例 class,它手动管理内存(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)
.