2012-03-28 2 views
-1

VC++コンパイラは、プログラマによって提供されていない場合、誰でも確認してもらえますか?VC++は、定義されていない場合、各クラスに対してデフォルトの 'delete'演算子を提供します。

VC++で生成されたディスアセンブリコードには、すべてのクラスに共通の 'new'演算子があると言われています。ただし、クラスごとに「delete」演算子が存在します。

delete bPtr; 
// The dis assembly code generated by vc++ for above line  
.... 
**call  Base::`scalar deleting destructor' (411253h)** 
.... 

delete [] bPtrArr; 

// The dis assembly code generated by vc++ for above line 
.... 
**call  Base::`vector deleting destructor' (41125Dh)** 
.... 

コールスタック:

malloc.exe!Base::~Base() Line 128 
malloc.exe!Base::`scalar deleting destructor'() + 0x2b bytes 
malloc.exe!wmain(int argc=0x00000001, wchar_t * * argv=0x00343250) Line 173 + 0x2b bytes 
malloc.exe!__tmainCRTStartup() Line 579 + 0x19 bytes 
malloc.exe!wmainCRTStartup() Line 399 
+0

はい、正しいです。 –

+0

@Dewあなたは質問をする際には注意が必要です。私は小文字で新しいものと削除を意味していると確信しています。しかし、その方が常に具体的で構文的には意味的に正しいと言えます。 – Invictus

+0

編集中のコードは、各クラスに対して 'delete'の証拠ではありません。スカラーの場合は 'delete'と配列の場合は' delete [] 'の間に違いがあることを示しています。これは妥当かつ予想通りです。 – Blastfurnace

答えて

4

号しかしnewdelete(小文字)標準で定義されているとコンパイラが提供されるようにしているここでは証拠があります。独自のバージョンが定義されていないクラスでは、デフォルトの実装が使用されます。

+0

生成されたアセンブリ解除コードは、コンパイラが各クラスに対して 'delete'演算子を提供すると感じさせます。 –

1

operator newoperator deleteは、非メンバ関数または静的メンバ関数のいずれかです。*デフォルトで定義されているのはグローバル名前空間です。デフォルトでは、クラスメンバは定義されていません。

あなたが見ているのは、デストラクタを削除していますです。これは、仮想デストラクタを持つクラスにのみ存在します。最も派生したオブジェクトを破棄するだけでなく、そのようなデストラクタは、最も派生したオブジェクトで直接delete演算子を使用した場合のようにメモリを解放します。これは、仮想ディスパッチなしでは実行できないため、デストラクタ内でdeleteが呼び出されます。

これは特定の種類のデストラクタであり、operator deleteではありません。 は既に他の場所に住んでいるoperator deleteと呼ばれています。

EDIT: MSVCは、最も派生した型が静的に判明している場合にも、このようになります。これは有効なアプローチですが、デストラクタを削除することの根拠は依然として仮想デストラクタに基づいています。この場合、削除デストラクタは常にdelete式で呼び出され、非削除デストラクタは他のものによって呼び出されます(returnステートメント、派生クラスデストラクタなど)。

*(彼らはメンバーであるときが、紛らわしい、staticキーワードは常にそれがダウン書かれていない場合でも、暗黙的に指定されます。)

+0

私の 'Base'クラスには仮想デストラクタ/メソッドがありません。 –

+0

@DewKumar:Huh。マイクロソフトではそうしたやり方をすることができますが、スタンダードでは許可しています。大きな違いはありません。 – Potatoswatter

+0

'delete'演算子の一般的なメソッドは、一般的な 'new'メソッドが提供されているので提供することもできます。なぜVC++が一般的な「削除」メソッドを提供していないのかを知りたかったのです。 –

1

いくつか他の人が「はい」がないので:なしを。

これは非常に顕著な実用上の結果をもたらすため重要です。

自動的に生成される唯一の演算子は、コピー代入演算子T& operator=(T const&)です。この演算子が生成される結果として、基本クラス代入演算子はデフォルトでは隠されています。そのような演算子を派生クラスで使用できるようにする必要がある場合は、演算子が自動的に生成されない場合は不要なusing –を使用する必要があります。

ここで、「新規」と書いていますが、その言語には「新しい」と書かれています。newで使用さnewキーワードがある、とは対照的に割り当て関数あるoperator new(のオーバーロードのセット)が、存在します。たとえば、new T()を書くと、クラスTのインスタンスに動的にメモリが割り当てられ、そのメモリ領域にTインスタンスが構築されますが、T::operator newは、Tで定義された割り当て関数の呼び出しにすぎません。それは1つを定義します。

デフォルトでは、new式はグローバル割り当て関数global operator newを使用します。しかし、クラスはそれ自身のカスタムを定義することができますoperator newnew式がコンパイルできるようにアクセス可能であれば、それが呼び出されます。

関連する問題