一般的做法是就是交换对象的值,(std::swap before c++11)但是代价太高.

高效做法是直接交换对象成员的指针.假设成员就是 private 指针,所谓 pimpl,类似设计模式里的桥接模式,或者叫依赖注入) http://www.cnblogs.com/cposture/p/4939971.html

最朴实的想法,全特例化 1 个自己类 W 的 swap 版本:

namespace std{
    template <> void swap<W>(W& a, W& b){
        swap(a.ptr,b.ptr);
    }
};

但是并不能直接访问 a 的私有变量 ptr.实现 1 个友元?或者用成员函数: 然后用 non-member 函数调用:

class W {
    void swap(W& a) {
        //why? 优先使用特定版本,否则使用std::map,这里是内置类型在swap,使用std::map
        using std::swap;
        swap(a.ptr,this.ptr);
    }
}
namespace std{
    //全特例化版本的swap
    template <> void swap<W>(W& a, W& b){
        a.swap(b);
    }
};

还有问题!如果 W 也是模板类:

namespace std{
    //std空间下的偏特例化版本的swap,编译不让过
    template <typename T> void swap<W<T>>(W<T>& a, W<T>& b){
        a.swap(b);
    }
};

此时在偏特化 std 空间的 function template,是不允许的. 最好的做法是另外用 1 个命名空间:

namespace WSpace {
    template <typename T> class W{...}
    template <typname T> void swap(W<T> & a,W<T> &b){a.swap(b);}
}

从调用者的角度:which swap? 现在可能会有 3 个选择:

1 std::swap
2 std::swap<W>
3 WSpace:swap<T>

希望的是有WSpace专属版本,则调用最佳,否则用std::swap

void dosth() {
    //如此声明,实现上面的效果.
    //选用顺序为3>2>1
    using std::swap;
    swap(obj1,obj2);
}

在 c++11 里,其实 std::swap 实现了高效版本,需要使用提供转移构造和转移赋值.

copy-and-swap 用于赋值构造

对我来讲,如果不用 copy-swap,可能会忘记了释放原来的 this 的内容.


A & operator=(const A & a) {
    if(this == &a) return *this;

    //可能忘记了
    delete_this();

    copy_from_A();
    return *this;
}

//注意参数是值类型,复制了临时变量
A & operator=( A a)
{
    swap(*this,a);
    //返回后释放a,即=左边的旧内存.
    return *this;
}