2012-11-15 17 views
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;將調用_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謝謝多納爾研究員的提醒

+2

re'memcpy'不,絕對沒有。 –

+0

當然,在非平凡類型中使用'memcpy'比goold old'std :: swap'安全得多(我希望你不介意這種諷刺);)。 –

+0

可能重複[什麼是複製和交換成語?](http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom) –

回答

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 ::交換代碼必須比你的交換代碼更快

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

我不認爲它是重點。如果string被嵌入到Buffer中,std :: swap(Buffer&,Buffer&)不會使用專門的string :: swap來避免重新分配字符串,可能是一個問題。 – xiaoyi

+1

@idy你不需要你的SWAP了,只需使用std :: swap – billz

+0

@billz,但是'std :: swap'會調用'string(const string&str)'來完成賦值。該字符串的賦值方法將動態分配內存。 – idy

0

它將爲這個特殊的緩衝區對象的工作,但未必是安全的畢竟,如果它與其他課程一起使用,它會發展。這是賦值運算符和/或類的拷貝構造函數的作用,以使其安全。

相關問題