самый безопасный способ поменять два экземпляра класса

использование 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


REF
то, что-это-The-копирование и замена-идиомы Спасибо, что напоминают Donal Fellows

1

Решение

Проблема с динамическим указателем 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);
}
2

Другие решения

Он будет работать для этого конкретного объекта Buffer, но может вообще не быть безопасным, если эволюционирует, если вы используете его с другим классом. Это роль оператора присваивания и / или конструктора копирования класса, чтобы сделать его безопасным.

0

По вопросам рекламы [email protected]