gpt4 book ai didi

c++ - 像 std::vector 这样的 vector 类的简单实现

转载 作者:行者123 更新时间:2023-11-28 06:24:44 25 4
gpt4 key购买 nike

我正在实现一个像 std::vector 这样的简单 vector ,并且我编写了一些函数,而不用担心它提供了什么样的异常安全保证。我对c++的异常了解一点,但是我没有写异常安全代码的经验。这是我的代码:

template <typename T>
class vector {
public:
vector(int _DEFAULT_VECTOR_SIZE = 10) :
size(0), array_(new T[_DEFAULT_VECTOR_SIZE]), capacity(_DEFAULT_VECTOR_SIZE) {}
void push_back(T& elem)
{
if (size == capacity)
resize(2 * size);
array_[size] = elem;
size++;
}

void pop_back()
{
--size;
}

void resize(int size_)
{
if (size_ > capacity)
{
T* temp = new T[size_];
memcpy(temp,array_,size*sizeof(T));
swap(temp, array_);
delete[] array_;
capacity = size_;
}
}

private:
T* array_;
int size;
int capacity;
};

所以我的问题是:我如何修改我的代码(函数),至少提供基本保证,或者一些编写异常安全代码以提供基本或强保证的技术?谢谢

最佳答案

异常安全有两种主要形式:

  1. 如果发生异常,您的程序将以正常状态结束。哪个未指定。
  2. 如果发生异常,您的程序将以原始状态结束。

您面临的主要挑战是处理赋值和复制构造函数抛出的问题。正如评论已经指出的那样,您不应使用 memcpy 因为它无法调用复制构造函数。复制 std::string 也应该复制字符缓冲区,例如,字符串 vector 是您应该支持的完全正常的类型。

那么,让我们看看 vector 的复制构造函数。它将需要复制源 vector 的每个元素。而且每个单独的拷贝都可以扔。如果其中一个字符串太长以至于拷贝抛出 std::bad_alloc 怎么办?

现在,异常安全意味着您让程序处于正常状态,因此没有内存泄漏。您的 vector 的复制 ctor 失败,因此 dtor 不会运行。那么谁来清理 T* array 呢?这必须在您的复制 ctor 中完成。

当复制失败时,不会有新的vector,所以你就免费获得了第二种异常安全。 (“强异常安全”)。但是接下来让我们看一下赋值运算符,v2 = v1。您将覆盖一个旧 vector 。如果您先执行 .resize(0) 然后复制所有元素,您可能会在复制过程中遇到异常。你原来的 vector 内容没有了,新的内容不完整。不过,您还没有泄漏任何内存,也没有复制半个元素。

为了确保分配安全,有一个简单的技巧:首先将源 vector 复制到临时 vector 。如果失败,没问题(见上文)。我们还没有到达目的地。但如果赋值成功,我们将交换临时 vector 和目标 vector 的 array* 指针、sizecapacity。交换指针和交换整数是安全的(不能抛出)。最后,我们让临时 vector 超出范围,这会破坏不再需要的旧 vector 元素。

因此,通过对临时对象执行所有危险操作,我们确保任何异常都不会触及原始状态。

您需要检查所有方法以查看是否会出现这些问题,但模式通常是相似的。如果元素复制或元素分配抛出异常,请不要泄漏 array,请将该异常传播给调用者。

关于c++ - 像 std::vector 这样的 vector 类的简单实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28720595/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com