2013-07-22 28 views
0

例如考慮認爲,在堆上分配的緩衝區的模板容器類:深拷貝到C-陣列的塊上堆

T *_buffer = new T[SIZE] 

只是一個簡單的指針類型T.

的Ç陣列

此課程是模板化的。不過,我在執行對象的深層副本到我的緩衝區時遇到問題。

在我的單元測試,我設置了一個測試類:

class test 
{ 
public: 
    int* _ptrInt; 
    test() {_ptrInt = nullptr;} 
    test(const int i) 
    { 
     _ptrInt = new int; 
     *_ptrInt = i; 
    } 
    test(const test& other) 
    { 
     _ptrInt = new int; 
     *_ptrInt = *other._ptrInt; 
    } 
    ~test() 
    { 
     delete _ptrInt; 
    } 
}; 

我的容器我呼籲設置,通過一個臨時的數據:

container.set(0, test(5)); 

// destructor called on copy immediately after statement, invalidating deep copy in buffer 
void set (const int& index, const T& data) 
{ 
    int i = realign(index); 
    T copy = data; 
    _buffer[i==SIZE?i-1:i] = copy; // ternary statement and index work 
} 

然而,_buffer需要複製的一個引用,當拷貝超出範圍時,它刪除_buffer中保存的相同指針。我試圖強制_buffer按值分配。但我沒有運氣。

  • 的memcpy仍然複製指針指向同一個地址
  • 測試拷貝構造函數正確調用
  • 移動語義需要類具有轉移構造
  • 的std ::向量在某種程度上實現此複製正確,無論是其T/T *,堆/棧,有/無移動構造函數,所以我知道它必須能夠

有沒有一種方法,我可以通過值分配到堆上的_buffer?

回答

3

「按值分配」。但是,test類沒有實現賦值運算符operator=,因此該賦值調用由編譯器生成的默認賦值運算符,該運算符只是逐個成員複製成員。因此,分配淺的問題。

此外,如果other._ptrIntnullptr,則您的複製構造函數將會爆炸。

+0

你是對的。默認的賦值運算符是淺拷貝,這給了容器不正確的副本。然而,上面這個同樣的類在std :: vector中工作,但我確定他們如何在那裏實現深度複製。 – Igneous01

+0

@David'std :: vector'做了一些棘手的事情,以避免默認 - 初始化其緩衝區,並實際上覆制 - 從插入的值初始化元素到位。如果'vector'從不需要重新分配緩衝區並複製活動元素,測試可能會成功。 – Casey