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

the most safe way to swap two class instance

本文关键字:实例 安全 方法 两个 交换      更新时间:2023-10-16

使用 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));
}

这是一种安全的方式吗???

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


裁判什么是复制和交换成语 感谢Donal Fellows的提醒

问题出在动态分配的指针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::交换代码应比您的交换代码快

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);
}

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