c++ - 如何实现 vector::clear()? (学习目的)

标签 c++ vector

我正在尝试实现我自己的 vector 类(用于学习目的)。目前我卡在 vector::clear() 上,我该如何实现它?总不能这样吧?

void clear() {
    for (size_t i = 0; i < _size; ++i) {
        _data = 0;//can't work with custom class
    }
}

或者

void clear() {
    delete[] _data;
    _data = new T[_cap];
    _size = 0;
}//can we make it better?

或者像这样简单:

void clear() {
    _size = 0;//fastest, but user can still access the data
}
T& operator[](size_t pos) {
    if (pos >= _size) throw;//added to prevent from accessing "cleared" data
    return _data[pos];
}

通过 libcxx 做了一些挖掘并发现他们使用 alloc_traits::destroy , 这会破坏 _data 中的每个元素???
这是我的类属性

T* _data;
size_t _size;
size_t _cap;

最佳答案

如果您保持容量大于大小,这意味着您需要考虑分配的不包含任何对象的内存。这意味着 new T[_cap] 方法根本不起作用:

  • 首先也是最重要的是,您的 vector 不适用于默认不可构造的对象
  • 即使是那些,您创建的对象也会比请求的多,而且对于某些对象而言,构建的成本可能很高。
  • 另一个问题是,当你push_back时,当你仍然有能力时,你将对对象进行赋值而不是构造(因为对象已经存在)

因此您需要将内存分配与对象创建分离:

C++17 为此目的引入了一些实用函数,例如:std::uninitialized_default_construct , uninitialized_copy , std::destroy ETC。;在 Dynamic memory management 中找到更多信息

如果你想像 std::vector 那样更通用,你可以使用 allocators相反。


考虑到这一点,现在回答您关于clear 的具体问题。 std::vector::clear 的行为是:“从容器中删除所有元素。此调用后,size() 返回零。[...] 保持 vector 的 capacity() 不变”。如果您想要相同的行为,这意味着:

void clear() noexcept
{
    for (T* it = _data; it != _data + _size; ++it)
        it->~T();

    // or
    std::destroy(_data, _data + size);

    _size = 0;
}

如您所见,实现类似 std::vector 的东西绝非易事,需要一些专业知识和技术。

并发症的另一个来源来自 strong exception safety .让我们仅考虑 push_back 的情况作为示例。一个简单的实现可以做到这一点(伪代码):

void push_back(const T& obj)
{
    if size == capacity
         // grow capacity
         new_data = allocate memory
         move objects from _data to new_data
         _data = new_data
         update _cap

    new (_data + _size) T{obj}; // in-place construct
    ++_size;
}

现在想想如果一个对象的移动构造函数在移动到新的更大的内存时抛出异常会发生什么。你有内存泄漏,最糟糕的是:你的 vector 中有一些对象处于移动状态。这将使您的 vector 处于无效的内部状态。这就是为什么 std::vector::push_back 保证:

很重要
  1. 运营商成功或
  2. 如果抛出异常,则该函数无效。

换句话说,它保证它永远不会让对象处于“中间”或无效状态,就像我们天真的实现所做的那样。

关于c++ - 如何实现 vector::clear()? (学习目的),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63276697/

相关文章:

c++ - 循环复制是否比 memcpy() 效率低?

c++ - 在 MS VC 2013 Express 中将 C++ dll 从 32 位转换为 64 位

c++ - 使用 GPC 或 Clipper 计算多边形相交面积

C++ RGB 图像数据叠加到二维数组中( vector 的 vector )

C++ - vector 迭代器不可递增错误

c++ - 在 xcode/objective c 中使用 c++

C++ 向后正则表达式搜索

c++ - 如何从 vector 中删除元素并更新迭代器?

c++ - 无法将 NULL 发送到获取 vector 的函数

C++——从二进制文件中读取动态分配的 vector