1

用于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;将调用 的复制构造函数_TxBuffer::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可能是安全的。这是比较:c99 vs. c++0x


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

4

2 回答 2

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);
}
于 2012-11-15T08:42:53.250 回答
0

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

于 2012-11-15T08:48:11.887 回答