Constおよび非constと同じオブジェクト、正しく動作するためにはどうすればよいですか?
-
20-12-2019 - |
質問
私は次の形式の機能を持っています
return_type function(const argument_type & a, argument_type & b);
同じオブジェクトが次のように渡された場合 a
と b
, 、関数を続行することはできますか(それによって潜在的に変更することができますか)、または停止できますか?
私はコンパイラの仮定がその場合にどのように伝播するかについての知識を持っていません。
私の推測では、それが非constとして渡されるための非constの仮定があるということです b
十分であり、変更を許可する必要がありますが、それは推測です。
ほとんどの答えはあることについてでした エイブル 変更するには a
または b
, 、または非constメソッドを呼び出します。私は両方と同じオブジェクトを渡すと知っています const
と non-const
私にはできる私の疑問は、関数が戻ったときにプログラムを離れ、コンパイラの仮定をブレーキすることができるかどうかという状態にあります。:
class A(){
int value;
}
void function1(const A & arg1);
void function2(A & arg1);
void function3(const A & arg1, A & arg2);
A a;
a.value=5;
function1(a);
if(a.value==5){/*...*/;} // the if can be optimized out to true, because [a] was const
a.value=5;
function2(a);
if(a.value==5){/*...*/;} //must be checked, [a] could have been modified
a.value=5;
function3(a, a);
if(a.value==5){/*...*/;} // ???
私が見つけた最も似たような質問(しかし実際にはそうではありません)
解決
の問題
return_type function(const argument_type & a, argument_type & b);
.
と呼び出しfunction( o , o )
は、関数がおそらく
-
正式な引数
b
を介してオブジェクトを変更しながら -
正式な議論
a
を変更しないままであることを期待しています。
だからあなたはおそらく機能の仮定を壊し、その結果、誤った結果やクラッシュ。
デザインによってがこの種の署名、すなわちコピー割り当て演算子を持つ関数が1つあります。その定数の正式な引数a
は、引数を指定した例外、およびその可変の正式な引数です(それを呼び出すことができる場合)暗黙の*this
です。自己参照(引数のエイリアシング)を確認することも、コピーしてスワップすることもできます。
まとめ、引数a
と同じオブジェクトを持つ関数を安全に呼び出すことができるかどうか、および引数b
が関数によって異なりますが、機能の仮定に違反する可能性があるため、正式な前提条件として引数はさまざまなオブジェクトを参照しています。
他のヒント
その関数が2回与えられた同じ引数で呼び出される可能性があるかどうかを決定します。
とにかく、アルゴリズムの正当性がそれに依存しないか、保証がない限り、同じオブジェクトを2回取得するかどうかを判断しないでください。
彼らは実行時にまったく同じ意味で同じものとまったく同じものと同じように渡されます。
const
との違いはコンパイル時にのみ発生します。コンパイラは、このconst
オブジェクトのプロパティを変更しようとしていないことを確認してください。
私の推測では、非const bとして渡されるための非const仮定で十分であり、変更を許可する必要がありますが、それは推測です。
はい。, function
非を呼び出すことができます-const
経由のメソッド b
しかし、経由ではありません a
.
直感的に、これは次のことを意味します function
を介して渡されたオブジェクトを変更することができます。 const
参考文献 a
同じオブジェクトがnonを介しても渡された場合-const
参考文献 b
.
一般的には, const
あなたができることやできないことについてのみ保証を行います const
変数。を参照する他の変数があるかもしれません const
変数、または、その中のオブジェクトに、それは可能にすることができます const
それが変更されているかのように見えない関数によって変更される変数 const
変数。
あなたのケースに戻ってくると、それはあなたよりも高いレベルの関数とクラスまでです function
を使用して変更できるものと変更できないものについての制約を強制します const
パラメータ、メンバ関数など