2009-08-05 5 views
0

私に興味を持って、私の記事の1のコメント:どのメンバ関数が突然変異するかをコンパイラがどのように決定するのですか?

Me too。私はアクセサ/ミューテータにも同じ名前を付けます。

私はいつも同じ名前のミューテータの代わりにsetBar(int bar)を使用していたので、私はこれについて疑問に思っていました。私は知りたい:コンパイラは、const識別子に基づいて実行時に何が突然変異するかを決定することができますか、それはパラメータを持つため同じ関数名を使用できますか?

これは罰金コンパイルします:

class Foo 
{ 
    int bar_; 

    public: 
     int bar() { return bar_; } 
     void bar(int bar) { bar_ = bar; } 
} 

または私はこの(私はちょうどこの上で私と一緒に実行して、私はとにかくこれを実行する必要があります実現)しなければならないん

int bar() const { return bar_; } 

Iドンどちらがどちらであるかは分かりません。 Constの正確さが重要なので、私はコンパイラが過度の負荷に異議を唱えることを望んでいると思います。

なぜこのように動作しますか?

+0

あなたのコードは不正です。 int bar()のようになります。const {return bar_; } 私は推測する。戻り値の型はコード内で失われます。 –

+0

あなたは私のポスト全体を見ましたか、それとも私を倒そうとしていますか? =( – jkeys

答えて

4

コンパイラが最初に気がつくのは、関数に渡すパラメータの数と型です。これにより、barの過負荷が解消されてから、const -nessを調べる必要があります。

あなたはconstとしてbar()をマークするために失敗した場合、コンパイラはあなたがオブジェクトのインスタンスconstbar()を呼び出そうと、この最初の時間をお知らせします。

+0

OK、それはパラメータになります。ありがとう! – jkeys

2

コンパイラは、実際にオブジェクトを変更しない非constメンバ関数を書くことを妨げることはありません。これはconst-correctnessの違反ではなく、オブジェクトがconst参照によって変更されないことを保証します。ここでの原則は、constは関数が突然変異しない可能性があり、非constは関数が望むならば自由に突然変異することを意味するということです。突然変異を約束し、コンパイラに次のように強制する方法はありません。私はこれがあまりにも漠然としているので、呼び出し元に何らかの使用を保証することはできません。

constオブジェクトで非constメンバ関数を呼び出そうとすると、コンパイラは対処します(実際にはmutateかどうかは関係ありません)。唯一重要なことはconst宣言されているかどうかです。

0

わかりやすくするために、コンパイラは、非constメソッドがそのオブジェクトに対して呼び出される場合、オブジェクトが変更されることを前提としています。

したがって、constメソッドでは、データメンバの1つ、またはクラスの別の非constメソッドの非constメソッドを呼び出すと、コンパイラはエラーを通知します。

オペレータをメソッドと見なすこともできます(いくつかの演算子はメソッドではなくfriendif関数として定義できますが、簡略化のために...)。たとえば、代入演算子(operator =)はデフォルトで非constです。あなたは

void MyClass::MyConstMethod() const 
{ 
    classMember = value; 
} 

のようなコンパイラはあなたがconstのメソッド内でconstオブジェクトである、classMember、の代入演算子と呼ばれることを考えるだろう何かをすればそれは意味します。 operator =はconstではないので、コンパイラエラーが報告されます。

関連する問題