web-dev-qa-db-ja.com

constへのポインターの削除(T const *)

Constポインターに関する基本的な質問があります。 constポインターを使用して非constメンバー関数を呼び出すことはできません。ただし、constポインターでこれを行うことは許可されています。

delete p;

これは、本質的に非const 'メソッド'であるクラスのデストラクタを呼び出します。なぜこれが許可されているのですか?これをサポートするだけですか?

delete this;

それとも他の理由がありますか?

81
Naveen

サポートすることです:

// 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オブジェクトをまったく使用できません。

103
anon

このように言えば、were n'tが許可されている場合、const_castを使用せずにconstオブジェクトを削除する方法はありません。

意味的に、constはオブジェクトが不変であるべきであることを示すものです。ただし、オブジェクトを削除してはいけないという意味ではありません。

45
PaulJWilliams

コンストラクタとデストラクタを「メソッド」と見なすべきではありません。これらは、クラスのオブジェクトを初期化および破棄するための特別な構造です。

「定数ポインター」は、オブジェクトが生きている間に操作が実行されても、オブジェクトの状態が変更されないことを示すことです。

5
Indy9000

別の見方をすると、constポインターの正確な意味は、そのオブジェクトまたは他のポインターまたは同じオブジェクトへの参照を介して表示される、指す先のオブジェクトに変更を加えることができないということです。しかし、オブジェクトが破壊されると、現在削除されたオブジェクトが以前占有していたアドレスへの他のすべてのポインターは、そのオブジェクトへのポインターではなくなります。それらは同じアドレスを保存しますが、そのアドレスはオブジェクトのアドレスではなくなりました(実際、別のオブジェクトのアドレスとしてすぐに再利用される可能性があります)。

この区別は、C++のポインターが弱参照のように動作する場合、つまりオブジェクトが破棄されるとすぐに、それに対するすべての既存のポインターがすぐに0に設定される場合、より明白になります。 (これは、実行時にすべてのC++プログラムに課すには費用がかかりすぎると考えられる種類のことであり、実際、完全に信頼できるものにすることは不可能です。)

[〜#〜] update [〜#〜]:9年後にこの記事を読んでいると、弁護士のようです。あなたの元の反応が理解できるようになりました。突然変異を禁止するが破壊を許可することは明らかに問題です。 constポインター/参照の暗黙のコントラクトは、それらの存在がターゲットオブジェクト(自動ガベージコレクション)の破壊のブロックとして機能することです。

これに対する通常の解決策は、代わりに他のほとんどすべての言語を使用することです。

5

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オブジェクトへのnon-constポインターを混同しました。

そうは言っても、

delete aConstPointer; // legal
delete aPointerToConst; // legal

ここで他の回答で既に述べた理由により、どちらかを削除することは合法です。

5
Oktalist