1

2 つのクラス インスタンスを交換するために使用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));
}

それは安全な方法ですか?

UPDATES std::swapは c++0x で安全かもしれません。これは比較です: c99c++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 に答える