constポインタに関する基本的な質問があります。constポインターを使用して非constメンバー関数を呼び出すことは許可されていません。ただし、constポインターでこれを行うことは許可されています。
delete p;
これは、本質的に非const 'メソッド'であるクラスのデストラクタを呼び出します。なぜこれが許可されるのですか?これをサポートするだけですか?
delete this;
それとも他の理由がありますか?
回答:
サポートすることです:
// dynamically create object that cannot be changed
const Foo * f = new Foo;
// use const member functions here
// delete it
delete f;
ただし、問題は動的に作成されたオブジェクトに限定されないことに注意してください。
{
const Foo f;
// use it
} // destructor called here
constオブジェクトでデストラクタを呼び出すことができなかった場合、constオブジェクトをまったく使用できませんでした。
const Foo * f
またはFoo const * f
Fooへのconstポインタではありません。Fooをconstするのはpoinerです。Foo * const f
Fooへのconstポインタです。
このように言えば、許可されていない場合、const_castを使用せずにconstオブジェクトを削除する方法はありません。
意味的には、constは、オブジェクトが不変でなければならないことを示します。ただし、これはオブジェクトを削除してはならないことを意味するものではありません。
constポインターを使用してconst以外のメンバー関数を呼び出すことは許可されていません。
はい、そうです。
class Foo
{
public:
void aNonConstMemberFunction();
};
Foo* const aConstPointer = new Foo;
aConstPointer->aNonConstMemberFunction(); // legal
const Foo* aPointerToConst = new Foo;
aPointerToConst->aNonConstMemberFunction(); // illegal
非constオブジェクトへのconstポインターと、constオブジェクトへの非constポインターを混同しました。
そうは言っても、
delete aConstPointer; // legal
delete aPointerToConst; // legal
ここで他の回答ですでに述べられている理由から、どちらかを削除することは合法です。
別の見方をすると、constポインターの正確な意味は、そのオブジェクトや他のポインター、または同じオブジェクトへの参照を介して表示される、ポイントされたオブジェクトに変更を加えることができないということです。ただし、オブジェクトが破壊されると、以前に削除されたオブジェクトが占めていたアドレスへの他のすべてのポインタは、そのオブジェクトへのポインタではなくなります。それらは同じアドレスを格納しますが、そのアドレスはもはやどのオブジェクトのアドレスでもありません(実際、すぐに別のオブジェクトのアドレスとして再利用される可能性があります)。
この区別は、C ++のポインターが弱参照のように動作する場合、つまりオブジェクトが破棄されるとすぐに、オブジェクトへのすべての既存のポインターがすぐに 0
。(これは、実行時にコストがかかりすぎてすべてのC ++プログラムに課すことができないと考えられる種類のことであり、実際、完全に信頼できるものにすることは不可能です。)
更新:9年後にこれを読み返すと、それは弁護士っぽいです。私は今あなたの最初の反応が理解できると思います。突然変異を禁止するが破壊を許可することは明らかに問題があります。constポインター/参照の暗黙の契約は、それらの存在がターゲットオブジェクトの破壊(別名自動ガベージコレクション)のブロックとして機能することです。
これに対する通常の解決策は、代わりに他のほとんどすべての言語を使用することです。
std::unique_ptr<const T>
人生の終わりにどのように対処しますか?