パブリックオペレーターの新しい、プライベートオペレーターの削除:C2248を取得“プライベートメンバーにアクセスできません”新しいを使用するとき
-
10-07-2019 - |
質問
クラスには、演算子 new
および delete
がオーバーロードされています。 new
はパブリック、 delete
はプライベートです。
このクラスのインスタンスを構築すると、次のエラーが表示されます:
pFoo = new Foo(bar)
example.cpp(1):エラーC2248: 'Foo:operator delete':クラス 'Foo'で宣言されたプライベートメンバーにアクセスできません
しかし、ここでは delete
の呼び出しはないので、コンパイラのねじれた心の中で何が起こっているのでしょうか? :)
- エラーの理由は何ですか?
- メンバーの
CreateInstance
関数に頼らずに問題を解決することは可能ですか?
解決
new Foo()
を実行すると、2つのことが起こります。最初に operator new
が呼び出されてメモリが割り当てられ、次に Foo
のコンストラクタが呼び出されますと呼ばれます。そのコンストラクタがスローした場合、既に割り当てられているメモリにアクセスできないため、C ++ランタイムは適切な operator delete
に渡すことでそれを処理します。そのため、作成するすべての operator new
に対して、一致する operator delete
を常に実装する必要があります。そのため、アクセス可能にする必要があります。
方法として、両方をプライベートにし、パブリックメンバー関数( create()
など)から operator new
を呼び出すことができます。
他のヒント
これを確認します。下の段落の1つでは、newにアクセスするには削除が必要であると書かれています。基本的に、ヒープ上にオブジェクトを作成できるのは、それらを再び削除することもできる場合のみであると言われています。
C ++標準に従って、動的にメモリを割り当てるクラスがあり、コンストラクタ内で例外が発生した場合、メモリリークを避けるためにメモリを解放する必要があります。
ここでは、新しい演算子をpublicとして定義していますが、deleteはprivateです。
だからコンパイラは、私ができるように私に削除演算子へのアクセスを与えると言っています コンストラクタで例外が発生した場合にメモリリークを防ぎます。
delete演算子を定義しない場合、コンパイラーもエラーを出し、強制的に定義します。
-
" 1。エラーの理由は何ですか?"
sbiの答えは良いです。
-
" 2。メンバーのCreateInstance関数に頼らずに問題を解決することは可能ですか?"
はい。プライベートデストラクターを作成します。
クラスコンストラクターが例外をスローした場合、クラスで演算子newを呼び出すと、クラスの削除も使用されます。
ライブラリで例外が使用されていない場合は、コンパイラの例外「-fno-exceptions」を無効にすると、エラーは表示されなくなります。 (Visual Studioでは、「C / C ++」、「Code Generation」、「C ++例外を有効にする」>" No(-fno-exceptions)")の下にあります)