【问题标题】:Deep copy into block of c-array on heap深度复制到堆上的 c 数组块中
【发布时间】:2013-07-21 20:56:20
【问题描述】:

例如,考虑一个模板容器类,它包含一个在堆上分配的缓冲区:

T *_buffer = new T[SIZE]

只是一个指向 T 类型的 c 数组的简单指针。

这个类是模板化的。但是,我在将对象深拷​​贝到缓冲区时遇到问题。

在我的单元测试中,我设置了一个测试类:

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;
    }
};

在我调用 set 的容器上,传递一个临时数据:

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::vector 以某种方式实现了这个以正确复制,无论它的 T/T*、堆/堆栈、带/不带移动构造函数,所以我知道它一定是可能的

有没有一种方法可以按值分配给堆上的_buffer?

【问题讨论】:

    标签: c++ templates containers deep-copy


    【解决方案1】:

    “按价值分配”。但是,您的 test 类没有实现赋值运算符 operator=,因此赋值调用编译器生成的默认赋值运算符,该运算符只是逐个成员复制。因此,浅层分配的问题。

    另外,如果other._ptrIntnullptr,您的复制构造函数将会爆炸。

    【讨论】:

    • 你是对的。默认的赋值运算符是浅拷贝,它给容器提供了不正确的拷贝。然而,上面这个相同的类在 std::vector 中工作,但我确定他们是如何在那里实现深度复制的。
    • @David std::vector 做了一些棘手的事情来避免默认初始化其缓冲区,并且实际上从您插入的值中复制初始化元素。如果 vector 不必重新分配其缓冲区并复制活动元素,则测试可能会成功。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    • 1970-01-01
    • 2014-11-03
    • 2012-08-21
    相关资源
    最近更新 更多