operator new()は、デフォルトのコンストラクターの存在に応じて、delete()が削除された場合の動作が異なります。


17

演算子new()を使用してクラスCの新しいオブジェクトを作成すると、ここでエラーが発生します。

class C
{
public:
    C() {}
    virtual ~C() {}

    void operator delete(void*) = delete;
};


int main()
{
    C* c = new C;
}

C2280: 'void C::operator delete(void *)': function was explicitly deleted

私は交換するときでもC() {}C() = default; か、そのコンパイラが(私はと同じ効果を持つと信じデフォルトコンストラクタを挿入するように、行を削除= default)、コードはコンパイルして実行します。

コンパイラが生成したデフォルトのコンストラクタとユーザー定義のデフォルトのコンストラクタの違いは何ですか?

私はこの投稿でいくつかのヒントを得ましたが、デストラクタが仮想なので、ここのクラスC(ユーザー提供のコンストラクタなし)は簡単ではありませんよね?

最新のVisual Studio、c ++ 17でコンパイルされています。


3
確かではありませんが、デフォルトのコンストラクタはnoexcept
Sebastian Redl

1
g ++では再現できません。operator delete()コンストラクターが手動で記述されているか、暗黙的に生成されているかに関する同様の診断。これは私の期待と一致していnewますoperator delete()。式によって例外がスローされる可能性があるため、コンパイラはにアクセスする必要があります。
ピーター

@SebastianRedlあなたが正しい、追加noexceptするとコードがコンパイルされますが、どうやって...?
yeshjho

1
@Peter例外はコンストラクターによってのみスローされるため、それがnoexceptSebastianRedlで言及されている場合は、への呼び出しをoperator delete含める必要はありません。また、g ++は、デストラクタが仮想である場合にのみ文句を言います。それ以外の場合は、コンストラクターがスローしている場合でも、常にコンパイルされます。
クルミ

@LeDYoMあなたのリンクはIPアドレスの解析に関するものであり、質問とは無関係のようです。間違ったリンクを投稿しましたか?
LF

回答:


17

コンパイラが生成したデフォルトのコンストラクタとユーザー定義のデフォルトのコンストラクタの違いは何ですか?

new式は対応するものoperator newを呼び出し、次にコンストラクターを呼び出します。コンストラクターが例外new式をスローする場合、operator new対応するを呼び出して(メモリーのリークを回避するため)の効果を取り消す必要がありoperator deleteます。後者が削除された場合、new式はそれを呼び出すことができず、結果としてコンパイラーになりerror: use of deleted function 'static void C::operator delete(void*)'ます。

noexceptコンストラクタは、おそらく、したがって、例外をスローすることができない対応するoperator deleteことにより呼び出されないように必要ではないnew表現。default些細なクラスのコンストラクタもあるnoexceptコンストラクタ。operator delete特別なスカラー削除デストラクターdelete基本クラスポインターによる式を有効にするための実装の詳細)がを呼び出すため、仮想デストラクターの存在は削除されないようにする必要がありますoperator delete

operator deleteで呼び出すことができない場合でも、コンパイラーを削除しないようにする必要があるかどうかは、C ++標準では規定されていないようnewです。gccただし、dの場合、対応するoperator deletein new式を呼び出しているようには見えませんdeleteバグレポートを投稿)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.