实现非复制交换功能

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::vectorstd::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).