2011-02-10 6 views
15
class Foo 
{ 
    int Bar; 

    public: 

    int& GetBar() const 
    { 
     return Bar; 
    } 
} 

GetBarconstの方法ですか?実際に何かを変えているわけではありませんが、「外の世界」にそれを変える手段を提供しています。参考文献を返すConstメソッド

+0

私はすでにあなたの質問に答えていると思います。さらに、例では、Barはすでに公開されています。 – XAder

+0

'&Bar'はint型ではなく' const int * '型です。コンパイラはこれがOKではないことを伝えるべきです。 –

+0

コンパイルを試しましたか?コンパイラはあなたに何を伝えましたか? –

答えて

18

...遅延評価、参照カウントを実装することが有用であることができ、これはおそらく何を意味するのかである:

class Foo 
{ 
    int Bar; 

    public: 

    int& GetBar() const 
    { 
     return Bar; // Removed the ampersand, because a reference is returned, not an address 
    } 
} 

そして、いや、これは有効ではありません。constでメソッドにタグを付けると、オブジェクトの内部状態に触れないことを約束するだけでなく、オブジェクトの状態を変更するために使用できるものを返さないことを約束します。非const参照は、GetBar()の範囲外のBarの値を変更するために使用される可能性があります。したがって、あなたは約束を守れないことを暗示しています。

メソッドを非constに変更するか、const参照を返すか、またはBarを約束の対象外にするか、mutableとマークする必要があります。例:mutable int Bar;mutableキーワードは、オブジェクトの論理定数がBarの状態に依存しないことをコンパイラに通知します。それで、あなたはそれで何でもしてください。

4

いいえ、あなたは次の代入行いカント以来: const int x; int &y = x;

あなたがが何ができるかはconst int x; const int &y = x;

ですそしてもちろんメソッドをオーバーロードし、CONSTと非constの両方を作成しても問題はありませんバリアント。

3

おそらくBarで、&Barではありません。

class Foo 
{ 
    int Bar; 

    public: 

    int& GetBar() const 
    { 
     return &Bar; 
    } 
}; 

int main(int argc, char** argv) 
{ 
    Foo x; 
    int y = x.GetBar(); 
    y = 5; 
    return 0; 
} 

をし、エラーました:とにかく、私はコモにこのコードを落とし、あなたが参照されたオブジェクトにアンパサンド演算子を使用する必要はありません参照を返すために、すべての

line 9: error: qualifiers dropped in binding reference of type 
      "int &" to initializer of type "const int" 
      return Bar; 
       ^
1

まず、 ; ポインタを取得したい場合は、それが必要です。だから、あなたはreturn Bar;と書いたかったと思う。

それでは、できません。 constメソッドではconstthisポインタがあります(あなたの場合はconst Foo *)。のフィールドへの参照はconstの参照になります。 constパス "。

したがって、const int &(参考文献のint &(メソッドの戻り値)を初期化しようとしているため、そのコードで行ったことを実行しようとするとコンパイルエラーが発生します。 from Bar)、これは明らかに禁止されています。

グラムは++、実際に言う:私は言っている

testconstref.cpp: In member function ‘int& Foo::GetBar() const’: 
testconstref.cpp:9: error: invalid initialization of non-const reference of type ‘int&’ from a temporary of type ‘const int*’ 

:)

場合は、代わりに、あなたは何の問題もないでしょうconstメソッドからクラスフィールドへconstの参照を返します。このようなフィールドもconst方法から変更可能ですコンパイラに指示しますmutableとしてマークされたフィールドを除くと


  1. 。この例外は、constメソッドがオブジェクトの "実際の"状態を "論理"状態を変更しない場合に変更できるようにするために導入されました。これはあなたがあなたのコードのタイプミスを持って
0

constメンバ関数の修飾子は、そのスコープ内でオブジェクトの状態を変更することを許可しません。コンパイラは、この関数がオブジェクトの状態をそのスコープ内で変更しているかどうかをチェックするだけです。別の例を取る -

class foo 
{ 
    int num ; 
    public : 
     foo(int anum) 
     { 
      anum = 10; 
     } 
     int getNum() 
     { 
      return num; 
     } 
}; 

foo obj; 
int& myNum = obj.getNum() ; // myNum is just an alias to the private class variable num 
myNum = 40; // Actually changes the content of the private variable. 

だから、コンパイラは、単にアクセス指定子をチェックする(すなわち、この変数にはアクセスかどうか、この範囲内であるかどうか)他のいくつかの変数に返されている場合ではなく、パブリック/プライベート/保護された変数のメモリ位置について。

1

constメソッドを使用している場合、クラスのメンバーはconstとみなされます。だからBarconst intではなくintですが、GetBar() constという文脈では "const int"です。したがって、非const参照またはポインタとしてそれを返すことはやってと同じくらい違法です:

const int y = 57; int& z = y;

これをyに2行目は、実際には(まだ)何も変わっていないにもかかわらず、constの-正しさを破ります。

あなたのクラスにポインタメンバーがある場合、唯一のconstはポインター自体であり、ポインターのものではありません。

はこのように、これは法的になります(多くの場合、「浅い」const性とも呼ばれる):

class A 
{ 
    Foo * foo; 

    public: 
    Foo * getFoo() const // legal. does not have to return const Foo * 
    { 
     return foo; 
    } 
}; 

注元のコードでは、あなたはそれがmutableた場合は非const参照によってBarを返すことが許されることを、これらのメンバーはメンバー機能の束縛に縛られていないからです。