「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > ベース ポインターを介した派生オブジェクトの配列の削除が C++ で未定義の動作になるのはなぜですか?

ベース ポインターを介した派生オブジェクトの配列の削除が C++ で未定義の動作になるのはなぜですか?

2024 年 12 月 23 日に公開
ブラウズ:747

Why is Deleting an Array of Derived Objects via a Base Pointer Undefined Behavior in C  ?

ベース ポインターを介した派生オブジェクトの配列の削除が未定義になる理由

C では、次の場合、配列を削除する動作は未定義になります。オブジェクトの動的タイプは静的タイプとは異なります。これは、C 03 標準 (5.3.5 [expr.delete] p3) で概説されています。「2 番目の選択肢 (配列の削除) では、削除されるオブジェクトの動的タイプがその静的タイプと異なる場合、動作は未定義です」 ."

説明のために、次のコード スニペットを考えてみましょう。

struct B { virtual ~B() {} };
struct D : B {};

B* p = new D[20];
delete[] p; // undefined behavior

ベース ポインタを使用して派生オブジェクトの配列を削除するのは直感的に見えるかもしれませんが、規格ではこれを未定義の動作として指定しています。これは、ベース ポインタ p が、最初の要素そのものではなく、配列内の最初の要素のベース サブオブジェクトを指しているためです。

配列のポリモーフィックな削除を実装するには、要素の型を取得し、動的キャストを実行する必要があります。次に単純な delete[] を実行します。ただし、ポリモーフィズムが利用されていない場合でも、これにより不要なオーバーヘッドが発生します。

したがって、未定義の動作や不要なオーバーヘッドを避けるために、配列はポリモーフィズム的に動作できないことを覚えておくことが重要です。代わりに、ポリモーフィックな動作が必要な場合は、個別に実装できます。

要約:

  • 正当な使用に対するペナルティを回避するために、配列はポリモーフィックな動作をサポートしません。
  • 必要に応じて、配列のポリモーフィックな削除を個別に実装できます。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3