push_back和pop_back的实现

时间:2016-06-06 17:53:05

标签: c++ push-back

我想了解std::vector<T>::push_backstd::vector<T>::pop_back如何在已分配的内存中创建和销毁对象?

我使用谷歌而我发现的只是人们只是与sizecapacity一起玩,以限制对内部动态阵列的访问,但我不认为事情是怎样的真正在标准实施中工作

注意:我没有要求标准实施,因为它很复杂但我很欣赏这种方法的基本实现

编辑:我想出了如何实现自己的自定义分配器

为简单起见,我只会显示自定义分配器中的重要功能

template <typename T>
T* allocate(std::size_t count) {
    return static_cast<T*>(::operator new(count * sizeof(T)));
}

template <typename T>
void deallocate(T* ptr, std::size_t count) {
    operator delete(ptr);
}


template <typename U, typename... Args>
void construct(U* ptr, Args&&... args) {
    new(ptr) U(std::forward<Args>(args)...);
}

template <typename U>
void destroy(U* ptr) {
    ptr->~U();
}

然后我在我自己定义的向量中使用类似这样的

int* buff = allocate<int>(8);
// This is like:
// std::vector<int> vec;
// vec.reserve(8);

int* last = &buff[0];
construct<int>(last, 32);
// This is like:
// vec.push_back(32);

++last;
construct<int>(last, 12);
// This is another push
// vec.push_back(12);

destroy(last);
--last;
// This is like: 
// vec.pop_back();


deallocate(buff, 8);
// This shoud be in:
// ~vector();

如果遗漏了某些内容,请检查一下......谢谢

1 个答案:

答案 0 :(得分:4)

所有带分配器的标准容器都使用allocator来构造或销毁元素:

23.2.1 [3]一般容器要求(N4296)

  

对于受本子条款影响的组件,声明一个   allocator_type,存储在这些组件中的对象应该是   使用allocator_traits :: construct构造   功能和破坏使用   allocator_traits :: destroy function

标准库中的默认分配器使用placement new来构造并调用析构函数来销毁元素:

20.7.9 [11]和[12]默认分配器(N4296)

template <class U, class... Args>
void construct(U* p, Args&&... args);

效果::: new((void *)p)U(std :: forward(args)...)

template <class U>
void destroy(U* p);

效果:p-> ~U()