C++ 高效swap实现
一般的做法是就是交换对象的值,(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;
}