1

環境

自分のバージョンのstd::vectorテンプレート クラスを実装しようとしています。ベクトルには、テンプレート引数の動的配列が含まれますT

_vec = new T[n];

明らかにT、ポインター、クラス、プリミティブ型など、あらゆる型にすることができます。v.resize(4)サイズのベクトルを1 回呼び出すと、次の仕様6に従って動的配列の最後の 2 つの要素を (配列を再割り当てせずに) 削除する必要があります。

n が現在のコンテナー サイズより小さい場合、コンテンツは最初の n 要素に縮小され、それ以降の要素は削除されます (そして破棄されます)。

破壊するということは、オブジェクトのデストラクタを呼び出すか、ポインタを含む他のプリミティブ型の場合は単にメモリ空間の割り当てを解除することを意味すると思います。

質問:動的に割り当てられた配列内のテンプレート要素を、割り当てを解除および再割り当てせずに破棄することは可能ですか?

私は何を試しましたか?さて、私は心からどこから始めればよいかわかりません:

  • どうやら、プリミティブ型でa を呼び出すべきではありません。delete
  • オブジェクトでデストラクタを明示的に呼び出すことができますがT、オブジェクトでない場合は機能しません。
  • _size内部カウンターを減らすことだけを考えました(push_back要素が上書きされるように) が、オブジェクトのデストラクタがすぐに呼び出されるわけではありません。
4

3 に答える 3

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()

これらの関数は、事前に割り当てられたメモリ内でオブジェクトを構築および分解しますが、それ自体はメモリを管理しません。

于 2013-04-03T09:01:59.700 に答える
1

new T[n]type のn オブジェクトがすでに作成されているため、必要なものではありませんが、 typeのオブジェクトまでのメモリTのみを割り当てたいとします。nT

placement-new 構文とplacement-delete 構文を読みたいと思うかもしれません。ウィキペディア

于 2013-04-03T08:35:51.730 に答える
0

FredOverflow は、オブジェクトの割り当てについて正しいです。

あなたの質問によると、オブジェクトと非オブジェクト (スカラー) を区別するだけです。<xmemory>Visual Studio 2010 ディストリビューションからの実際のコードがあります。

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

それらは、いくつかの特性クラスを使用して計算できる特別なフラグを使用した単純なディスパッチを使用します。

于 2013-04-03T09:06:05.020 に答える