交换两个类实例最安全的方法

时间:2012-11-15 08:39:21

标签: c++ swap

使用swap交换两个类实例,有时可能会抛出错误。

#include <iostream>
#include <string>
using namespace std;

#include <cstring>
class Buffer {
public:
    Buffer(const string& s): buffer(s) {}
    string buffer;
};

template<class _Tx>
void SWAP(_Tx& a, _Tx& b) {
    size_t size = sizeof(_Tx);
    char buffer[size];
    memcpy(buffer, &a, size);
    memcpy(&a, &b, size);
    memcpy(&b, buffer, size);
}

int main() {
    Buffer a("This is a"), b("This is b");
    swap(a,b);
    cout << a.buffer << endl;

    SWAP(a,b);
    cout << b.buffer << endl;
    return 0;
}

std::swap将执行以下操作:

template<class _Tx>
void swap(_Tx &a, _Tx &b) {
    _Tx t = a;
    a = b;
    b = t;
}

_Tx t = a;将调用_Tx的复制构造函数,在这种情况下为Buffer::Buffer(Buffer &e)。此方法尝试分配一些内存,这可能会导致一些错误。

我尝试使用其他方法而不是std::swap

template<class _Tx>
void SWAP(_Tx& a, _Tx& b) {
    char buffer[sizeof(_Tx)];
    memcpy(buffer, &a, sizeof(_Tx));
    memcpy(&a, &b, sizeof(_Tx));
    memcpy(&b, buffer, sizeof(_Tx));
}

这是一种安全的方式吗?

更新 使用c ++ 0x,std::swap可能是安全的。这是比较:c99c++0x


REF what-is-the-copy-and-swap-idiom 感谢Donal Fellows的提醒

2 个答案:

答案 0 :(得分:2)

问题在于动态分配指针buffer,为什么不使用std::string代替

复制构造函数签名是:

Buffer(const Buffer &e) 

现在交换对象:

int main(int agrc, char* argv[])
{
  Buffer a("This is a"), b("This is b");
  std::swap(a,b);
}

std :: swap代码应比SWAP代码快

template<class _Ty> inline
void swap(_Ty& _Left, _Ty& _Right)
{   // exchange values stored at _Left and _Right
  _Ty _Tmp = _Move(_Left);
  _Left = _Move(_Right);
  _Right = _Move(_Tmp);
}

答案 1 :(得分:0)

它适用于这个特定的Buffer对象,但如果你将它与另一个类一起使用,它可能根本不安全。它是赋值运算符和/或类的复制构造函数的作用,以使其安全。