解除分配(并调用析构函数)模板参数

时间:2013-04-03 08:33:05

标签: c++ dynamic-allocation

上下文

我正在尝试实现我的std::vector模板类版本。向量包含模板参数T的动态数组:

_vec = new T[n];

显然T可以是任何类型,指针,类,基元类型。如果在大小为v.resize(4)的向量上调用6,则显然应在this specification后删除动态数组的最后2个元素(不重新分配数组):

  

如果n小于当前容器大小,则内容将减少为前n个元素,删除超出(并销毁它们)的元素。

通过销毁我的意思是,我认为std库意味着,调用析构函数的对象,或者只是释放内存空间,如果它是任何其他原始类型,包括指针。

问题:是否有可能(如果是这样,如何)在不解除分配和重新分配的情况下销毁动态分配的数组中的模板元素?

我尝试了什么?嗯,我真诚地不知道从哪里开始:

  • 显然you shouldn't在原始类型上调用delete
  • You can显式调用对象上的析构函数,但如果T不是对象,则无效。
  • 我想过只减少内部_size计数器(以便将来会覆盖push_back个元素),但这不会立即调用对象的析构函数。

3 个答案:

答案 0 :(得分:2)

当您实现vector时,您可能希望将存储的管理和对象的管理分开。

使用allocator::allocate(size_type n)allocator::deallocate(pointer p, size_type n)管理存储,通常分别实现为return ::operator new(n * sizeof (T));::operator delete(p);

这些函数分配和释放内存,但不要为该内存中包含的对象调用构造函数或析构函数。

使用allocator::construct(U* p, Args&&... args);allocator::destroy(U* p);管理对象生命周期,这些生命周期通常分别实现为::new((void *)p) U(std::forward<Args>(args)...);p->~U()

这些函数构造和解构预分配内存中的对象,但不管理内存。

答案 1 :(得分:1)

new T[n]不是您想要的,因为它已经创建n类型的T 对象,但您只想分配内存最多nT类型的对象。

您可能希望了解展示位置新语法和展示位置删除语法。 Wikipedia

答案 2 :(得分:0)

FredOverflow关于对象分配是正确的。

根据您的问题,您需要做的只是将对象与非对象(标量)区分开来。 Visual Studio 2010发行版中有<xmemory>的实际代码:

template<class _Alloc> inline void _Destroy_range(
  typename _Alloc::pointer _First, typename _Alloc::pointer _Last, _Alloc& _Al);

template<class _Alloc> inline void _Destroy_range(
  typename _Alloc::pointer _First, typename _Alloc::pointer _Last, _Alloc& _Al, 
  _Nonscalar_ptr_iterator_tag);  // Object overload

template<class _Alloc> inline void _Destroy_range(
  typename _Alloc::pointer _First, typename _Alloc::pointer _Last, _Alloc& _Al, 
  _Scalar_ptr_iterator_tag);  // Non-object overload

他们使用带有特殊标志的简单调度,可以使用某些特征类来计算。