4

次のコードを検討してください。

class A 
{
public:
  A() {}
  ~A() {}
};

class B: public A
{
  B() {}
  ~B() {}
};

A* b = new B;
delete b; // undefined behaviour

私の理解では、C++ 標準では、b の削除は未定義の動作であると述べられています。つまり、何かが起こる可能性があります。しかし、現実の世界では、私の経験では ~A() は常に呼び出され、メモリは正しく解放されます。

B が独自のデストラクタを持つクラス メンバを導入した場合、それらは呼び出されませんが、ソース コードが 1 つのクラス メソッドのバグを修正するために継承が使用される、上記の単純な種類のケースにのみ関心があります。利用できません。

明らかに、これは自明ではないケースでは望んでいるものではありませんが、少なくとも一貫しています。示されているコードについて、上記が発生しないC++ 実装を認識していますか?

4

4 に答える 4

6

これは、C++ タグにおける終わりのない質問です。「予測可能な未定義の動作とは何ですか」。すべて自分で解決するのは簡単です。すべてのC++ コンパイラの実装を取得し、予測可能で予測不可能なものがまだ機能するかどうかを確認してください。ただし、これは自分で行う必要があります。

あなたが見つけたものを投稿してください。それは知っておくと非常に役立ちます。予測不可能なものが全体的に一貫した注釈付きの動作をしている限り。C++ コンパイラを書いている人が、自分の製品に注意を向けさせるのが非常に難しくなっています。慣例による標準化は、未定義の動作が多い言語で頻繁に行われます。

于 2010-12-23T22:59:20.160 に答える
3

私の知る限り、それが正しくない実装はありません。一方、POD 以外を入れると爆発するクラスを持つことは、バグと呼ぶのも無理はないほど悪いことです。

さらに、あなたの質問のタイトルは信じられないほど誤解を招くものです。はい、クラスのデストラクタを呼び出さないことは、現実世界の深刻な問題です。はい、入力セットを信じられないほど少数の現実世界のクラスに制限しても問題ありません。

于 2010-12-23T22:50:58.180 に答える
1

「示されているコードについて」、機能する実装が見つかる可能性はほとんどありません。つまり、そのようなエラーをキャッチするように特別かつ意図的に設計されたさまざまな「デバッグ」実装を考慮から除外した場合です。

于 2010-12-23T22:46:47.623 に答える
1

クラス B は、その内部に A のインスタンスと B の追加メンバーがあるため、ほとんどの場合、重要なケースでは A よりも大きくなります。仮想メンバーを導入すると、さらに悪化します。

したがって、~A が呼び出される間、この種のことがメモリ リークを引き起こす可能性があることは容易にわかります。基本的に保証されている ~A を呼び出さない可能性があるためではなく、メモリの管理方法による未定義の動作です。

于 2010-12-23T22:51:05.813 に答える