const メソッド内で self への非 const ポインタを介して self を変更する
質問
次の例では const
オブジェクトはそれ自体を変更できます const
メソッドでは、メソッド自体に次の方法でアクセスするためです。 non-const
ポインタ。(ideoneでも同じプログラム)
#include <iostream>
struct Object;
Object * g_pObject;
struct Object
{
Object():m_a(0){}
void ModifySelfViaConstMethod() const
{
g_pObject->m_a = 37;
}
int m_a;
};
int main()
{
Object o;
g_pObject = &o;
const Object & co = o;
std::cout << co.m_a << "\n";
co.ModifySelfViaConstMethod();
std::cout << co.m_a << "\n";
return 0;
}
私は C++ 標準を読むのがあまり得意ではないので、ここで質問します。
規格ではこれについて何と言っていますか?
a)const
このメソッドは、このようなことを行うときにオブジェクトが変更されないことを保証しません
b) それは明確に定義されており、コンパイルする必要がありますか
c) その他?
解決
これについて標準は何を言っていますか?
this
はconst Object *
型を持っている(言い換えて)、this
を介してメンバーを修正することも、Const Constメンバー関数を呼び出すことはできません。関数がアクセスできる可能性があるグローバルな変数を使用してできることについては何も言いません。関数が呼び出されたオブジェクトへの直接アクセスのみを制御します。
const
メソッドは、このようなものをするときにあなたのオブジェクトが変更されないままであることを保証しません
いいえではありません。関数がオブジェクトを変更しないという意図を示し、その意図を誤って破壊することに対する保護をいくつか提供します。それは、Promiseを破るために、一般的に乱雑なプログラマー、または(ここで)グローバル変数を介して制御されていない結合を使用することを妨げません。
それはそれが良好に定義されており、それはコンパイルされなければならない
はい。 const_cast
それ自体は一定ではありませんので、コンストラクト以外のポインタや参照を参照するのをやめるものは何もありません。メンバー関数のo
は、他のポインタを介して任意のオブジェクトではなく、const
を介してオブジェクトへのアクセスを制限します。
他のヒント
const
関数を宣言すると、「あなた自身の良い」です。
つまり、初期設計によると、実行時に呼び出されるオブジェクトを変更することは想定されていないため、const
を宣言します。
この関数の実装のいくつかの時点でオブジェクトの変更を終わらせると、コンパイラはあなたに言って、それが間違っていると言っているようになるでしょう。
もちろん、Compilerはそのような試みを識別することができます。与えられた例では、Compilerはthis
とthis
の比較が必要なため、問題を特定できず、実行時にそのような比較は行われます。
メソッドが次のように宣言されている場合 const
, 、コンパイラは、インスタンスが指すことを確認します。 this
ポインタは変更されません。変更しようとすると、 this
たとえば、コンパイラが失敗します。ただし、コンパイラはそれを知る方法がありません。 g_pObject
そして this
実際には同じインスタンスを指しています。これには実行時の比較が必要であり、コンパイラは内部で使用されるすべてのポインタの実行時の比較を実行して時間を無駄にすることはありません。 const
ひょっとすると、彼らは かもしれない 一致する this
ポインタ。したがって、変更する場合は、 Object
外部ポインタを介して、独自のチェックを行う必要があります。例:
void ModifySelfViaConstMethod() const
{
if (g_pObject != this)
g_pObject->m_a = 37;
}
C ++の恒常性はセキュリティではなく安全機器です。
恒常性が尊重されているコードはおそらく予想通りうまく機能します。
「私が何をしているのか知っている」場合は、const_cast
演算子とmutable
キーワードからBanal Cスタイルのキャストへの様々なツールのさまざまなツールを見つけることができます。