19


1

パブリックオペレーターの新規、プライベートオペレーターの削除:newの使用時にC2248「プライベートメンバーにアクセスできません」を取得

クラスには、演算子「new」と「delete」がオーバーロードされています。 「new」はパブリック、「delete」はプライベートです。

このクラスのインスタンスを構築すると、次のエラーが表示されます。

pFoo = new Foo(bar)
  • example.cpp(1):エラーC2248: 'Foo:operator delete':クラス 'Foo’で宣言されたプライベートメンバーにアクセスできません*

しかし、ここでは「削除」の呼び出しはないので、コンパイラのねじれた心の中で何が起こっているのでしょうか? :)

  1. エラーの理由は何ですか?

  2. メンバーに頼らずに問題を解決することは可能ですか 「CreateInstance」関数?

4 Answer


27


new Foo()`を実行すると、2つのことが起こります。最初に `operator new`が呼び出されてメモリが割り当てられ、次に Foo`のコンストラクタが呼び出されます。 そのコンストラクタがスローした場合、すでに割り当てられているメモリにアクセスできないため、C ++ランタイムは適切な「演算子削除」に渡すことでそれを処理します。 それが、あなたが書くすべての「operator new」に対して常に一致する「operator delete」を実装しなければならない理由であり、それがアクセス可能である必要がある理由です。

方法としては、両方をプライベートにし、パブリックメンバー関数( `create()`など)から `operator new`を呼び出すことができます。


3


thisを確認してください。 下の段落の1つでは、newにアクセスするには削除が必要であると書かれています。 基本的に、ヒープ上にオブジェクトを作成できるのは、それらを再度削除することもできる場合のみだという。


2


C ++標準に従って、動的にメモリを割り当てるクラスがあり、コンストラクタ内で例外が発生した場合、メモリリークを避けるためにメモリを解放する必要があります。

ここでは、所有するnew演算子をpublicとして定義していますが、deleteはprivateです。

そのため、コンパイラは、コンストラクタで例外が発生した場合にメモリリークを防止できるように、delete演算子へのアクセスを許可することを教えています。

delete演算子を定義しないと、コンパイラーもエラーを出して定義を強制します。


1


  • 「1.エラーの理由は何ですか?」 + sbiの答えは良いです。

  • 「2.メンバーに頼らずに問題を解決することは可能ですか CreateInstance関数?」+はい。 プライベートデストラクタを作成します。