4

例如,我尝试编写自己的vector,所以我只是这样写它的assign函数

template <typename T>
void Vector<T> :: assign(T *start, T *end)
{
    if (end - start > _capacity)
    {
        resize(end - start);
    }
    _size = end - start;
    delete []ptr;
    ptr = new T[_capacity];
    memcpy(ptr, start, end - start);
}

我之前有新的指针ptr,但我可以复制指针startend

为什么?非常感谢。

4

2 回答 2

4

第一个问题是这只适用于简单类型(读取 POD)。
任何带有构造函数/析构函数的东西都需要调用它们。

其次,这不是例外安全的。
它甚至不提供基本保证,更不用说强有力的保证了。

在修改对象之前,您需要完成所有异常不安全的工作。这意味着new必须在修改对象之前完成(并且绝对是在释放之前)。否则,您可能会抛出使对象处于无效状态(这可能看起来不错,但是如果您捕获异常并继续,您现在有一个包含指向已释放内存的指针的对象)。

所以即使你使用std::copy()你仍然做错了事。
我个人认为 std::copy() 的建议是红鲱鱼。它会正确地复制数据,但你的方法仍然很糟糕。您需要在复制和交换 idium 上使用扭曲。

template <typename T>
void Vector<T> :: assign(T *start, T *end)
{
    Vector<T> tmp(start, end);  // construct a temp object that allocates the memory.



    swap(tmp);                  // Swap the current object and the tmp objects data.
                                // When the tmp object goes out of scope it will delete
                                // what was the current objects data

}
于 2012-06-08T16:55:44.237 回答
3

以这种方式重用指针完全没问题,但在这里使用 memcpy并不安全,因为你不知道 T 是什么类型。如果 T 是字符串或向量之类的对象类型,则会导致未定义的行为。

要解决此问题,请将行更改为

std::copy(start, end, ptr);

这是安全的 C++ 方法。

希望这可以帮助!

于 2012-06-08T16:45:50.300 回答