繁体   English   中英

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

[英]the most safe way to swap two class instance

使用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的复制构造_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 vs. c++0x


REF what-the-the-copy-and-swap-idiom感谢 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::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);
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM