2011-11-15 11 views
4

可能性の重複:
Deleting a pointer to const (T const*)なぜ "const T *"が "operator delete"のtrivially "void *"に変換されるのですか?

void operator delete (void*); 
... 
const char *pn = new char, *pm = (char*)malloc(1); 
delete pn; // allowed !! 
free(pm); // error 

Demo

free()は関数なので、const void*void*に変換できません。しかし、operator delete(デフォルトまたは過負荷)の場合はなぜ許可されますか?

機能的に間違った構成ではありませんか?

+0

「void *」を削除するとどうにかUBですか、誰が気にしますか? – tenfour

+1

ここで答えています:http://stackoverflow.com/questions/755196/deleting-a-pointer-to-const-t-const –

+0

@tenfour、よく 'const T *'は 'T *'に変換してから'void *'に変換されます。だからUBではないはずです。さもなければ、すべての 'delete'sはUBです。もちろん、 – iammilind

答えて

2

私は@ JamesKanzeの答えにかなり同意しますが、おそらく誰かが標準が実際に言っていることを見たいと思うかもしれません。標準(§12.1/ 4)によると:

CONST及び揮発性セマンティクス(7.1.5.1) 建設オブジェクトに適用されません。このようなセマンティクスは、一番派生したオブジェクト(1.8)のコンストラクタが終了すると有効になります( )。

及び(12.4/2):

CONST及び 揮発性セマンティクス(7.1.5.1)を破壊対象物上に塗布されていません。そのようなセマンティクスは、最も派生したオブジェクト(1.8)のデストラクタが開始すると、 が終了するのを止めます。公平で

が、これは@Jamesが、もう少し具体的には、言ったことを再状態よりも少しありません:オブジェクトはだけは本当に時間から対象物と考えられているがCTORが終了(またはすべて ctors、継承が関与しています)、最初のdtorが始まるまでの間です。これらの境界の外側では、constとvolatileは強制されません。

+0

微妙な違いがあります。 Jamesは次のように述べています。 "*破棄後、あなたは' void * 'を残しています。スタンダードは、 "このようなセマンティクスは、最も派生したオブジェクト(1.8)のデストラクタが開始されると、だから、Jamesが言ったことから、誰かが、 'const'セマンティクスはデストラクタの実行中にまだ有効であると推測でき、間違っている可能性があります。しかし、それは本当にニックピッキングです。 –

4

そうではありません。 delete式はまずデストラクタを呼び出します。 破壊後には、void*が残っています。 (典型的な実装では、 は、実際には、デストラクタは、ほとんどの派生クラスに依存して呼び出すためにどのoperator delete() 以来、operator delete()関数を呼び出しています。)あなたのT const*はデストラクタでT*なり理由として

:これは任意のです とは異なる:

{ 
    T const anObject; 
    // ... 
} // destructor of anObject called here. With T*, not T const* 

? 1つは異なるルールを主張することができますが、最終的にはデストラクタは で特別なルールに従います。

+0

つまり、破壊は 'const'をキャストします。 –

+0

@MikeDeSimone:私は別の方法を見ます。 'const'は生きているオブジェクトにのみ適用されます。コンストラクターとデストラクタはこの生涯以外で実行されるため、適用されません。 –

+0

@MikeDeSimoneまたは無視します。とにかくタイプのついたデストラクタとコンストラクタがゲームをするので、もう1つの異常がありますか? –

関連する問題