2017-05-02 2 views
3

は、次のコードを検討:const参照の戻り値を持つオーバーロードされたメソッドが呼び出されないのはなぜですか?

#include <iostream> 

using namespace std; 

class A { 
    private: 
    int x; 
    public: 
    int& get_ref() { 
     cerr << "non const" << endl; 
     return x; 
    } 

    const int& get_ref() const { 
     cerr << "const" << endl; 
     return x; 
    } 
}; 

int main() { 
    A a; 
    a.get_ref() = 10; 

    cout << a.get_ref() << endl; 

    const int& y = a.get_ref(); 

    return 0; 
} 

Iはget_ref()方法(および標準誤差で出力const)の第2のバージョンを実行するa.get_ref()に第二及び第三の呼び出しを期待します。しかし、常に最初のバージョンが呼び出されたように見えます。 2つの異なるゲッターを実装し、適切なバージョンがコンテキストに基づいて呼び出されることを確認するにはどうすればよいですか?少なくとも3回目の呼び出しの場合

const int& y = a.get_ref(); 

2番目のバージョンは実行されますか。 (非エレガントな解決策は、例えばget_refget_const_refという異なる名前を使用することですが、回避できるかどうかを確認しようとしています)。

答えて

5

オーバーロードの解決は戻り値に依存せず、オブジェクトメンバ関数のために呼び出される。 aが非constオブジェクトである場合、a.get_ref()の場合、非constメンバ関数が常に呼び出されます。

あなたは呼び出されるのconstバージョンのconstにキャストすることができます

BTW
const_cast<const A&>(a).get_ref(); 

:それらに異なる名前を与えることは悪い考えではありません。だから我々はstd::cbeginstd::cendをSTLに持っているのです。

+0

感謝を!したがって、特に、これは、クラス内からの 'get_ref'への呼び出しが、(' const'にあなたが提案したものと同様に 'this'をキャストしない限り)最初の(非const)バージョンに解決されることを意味します。私は正しい? – PBM

+2

@PBMもっと正確に言えば、クラスのメンバ関数から 'get_ref'を呼び出すとき、解像度は' this'が 'const'または' non-const'を指しているかどうか、つまり最初に呼び出されるメンバ関数は 'const'です。か否か。つまり、 'const'メンバ関数の中で、' get_ref'を呼び出すと、constの 'get_ref'が呼び出されます。非constメンバ関数の中では、非constの 'get_ref'が呼び出されます。 – songyuanyao

0

過負荷解像度のみ(thisに対する暗黙の引数を含む)呼び出しの引数に関係しています。式a.get_ref()は、返された値がどうなるかに関係なく、同じオーバーロードに評価されなければなりません。これはC++の基本であり、あなたができることは何もありません。

あなたはconst -qualifiedバージョンを呼び出したい場合は、const -qualifiedオブジェクト式を使用:明確化のため

const int& y = const_cast<const A&>(a).get_ref(); 
+0

処理したい具体的な状況に基づいて、可能な限り回避策があります。あなたが* why *を指定してそのような振る舞いを望むなら、私は回避策を思いつくかもしれません。それは醜く落胆しますが、可能かもしれません。 – Angew

関連する問題