c++11 - c++move构造函数问题
PHP中文网
PHP中文网 2017-04-17 15:38:12
0
2
767
PHP中文网
PHP中文网

认证高级PHP讲师

全員に返信(2)
洪涛

上記は、コピー コンストラクターが呼び出される理由を説明しています。なぜそれが混乱するのかを説明しましょう。

まず、本質的な理由はベクトル拡張です。初期容量は 0 で、最初の演算は 1 に拡張され、2 番目の演算は 2 に倍増します。

Mac で Clang++ を使用しています。これが呼び出す stl 実装は libcxx である必要があります。これは、libcxx の Vector Push_back 実装のソース コードから確認できます。

ソースコードはここでご覧いただけます https://github.com/llvm-mirro...

リーリー

__push_back_slow_path の実装は次のようになります

リーリー

最初に容量が拡張され、__recommend が拡張作業を行ってから、新しいコンテンツが構築され、__a の後半の先頭に配置されることがわかります。移動またはコピーでき、最後に _swap_out_circular_buffer 関数を実行します。
__swap_out_circular_buffer の実装は次のとおりです:

リーリー

反復子とサイズの処理に注目する必要はありません。重要な点は、前のベクトルのデータを新しいベクトル メモリ領域にコピーまたは移動する役割を担う __alloc_traits::__construct_backward です。
__construct_backward の実装はこんな感じ

リーリー

move_if_noExcept から、移動操作を実行するには noExcept でなければならないことがわかります。この操作は end から開始され、begin まで反復子が減少するため、逆の順序になります。


最初のpush_backを実行するときは、容量が不足していることを確認し、__push_back_slow_path関数を実行し、ベクトルを1に拡張し、移動コンストラクターを実行します。元のベクトルは空であるため、それ以上の処理は必要ありません。

これは初めての印刷です Move constructor is called. source: hello

2回目のpush_back実行時は、容量が足りないことを確認し、__push_back_slow_path関数を実行し、ベクトルを2に展開し、移動コンストラクタを実行します。

これは 2 刷目です Move constructor is called. source: world

次に、__swap_out_circular_buffer を実行し、__alloc_traits::__construct_backward を呼び出します。移動コンストラクターは noExcept ではないため、コピー コンストラクターを 1 回呼び出します。

これは 3 番目の印刷です Copy constructor is called. source: hello


要素が増えると、その後のコピー コンストラクターの実行順序が元のベクトルの順序と逆になることがわかります。その理由は、上記でも述べたとおり、演算は末尾から始まり、反復子は減少し続けます。始めます。

いいねを押す +0
迷茫

移動コンストラクターは noExcept ではないからです。移動コンストラクターを noExcept(true) として宣言すると、ベクターはコピー コンストラクターを呼び出しません。

vector の Push_back には拡張ストレージ領域が必要になる場合があります。このプロセスには、元の記憶領域から新しく適用された記憶領域への元のデータのコピーが含まれます。同時に、push_back は、要素を追加するプロセス中に操作で例外がスローされた場合に、コンテナーが Push_back 前の状態を維持することを保証する必要があります。したがって、例外をスローする可能性がある移動コンストラクターを呼び出すことはできません。意味的に言えば、移動構築操作を中断する (例外をスローする) とデータ破損が発生するためです。

意味的に言えば、データ破損を引き起こさないため、例外をスローする可能性のあるコピー コンストラクターを呼び出します。もちろん、コピー コンストラクターで何かを行うこともできます。

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!