2017-05-02 3 views
3

Betrachten Sie das folgende Stück Code:Warum wird die überladene Methode mit const Referenz Rückgabewert nicht aufgerufen?

#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; 
} 

ich den zweiten und dritten Anrufe a.get_ref() erwarten, dass die zweite Version von get_ref() Methode (und Ausgang const auf dem Standardfehler) laufen. Aber es sieht so aus, als ob immer die erste Version aufgerufen wird. Wie kann ich zwei verschiedene 'Getter' implementieren und sicherstellen, dass die richtige Version basierend auf dem Kontext aufgerufen wird? Das heißt, zumindest für den dritten Anruf

const int& y = a.get_ref(); 

die zweite Version wird ausgeführt? (Eine nicht-elegante Lösung wäre, verschiedene Namen zu verwenden, zB get_ref und get_const_ref aber ich versuche, zu sehen, ob das vermieden werden kann.)

Antwort

5

Überlastung Auflösung hängt nicht von Rückgabewerte, sondern nur Argumente, einschließlich des Objekts für die Mitgliederfunktion aufgerufen werden. a ist ein nicht-konstantes Objekt, dann wird für a.get_ref() die nicht konstante Elementfunktion immer aufgerufen.

Sie es const für die const-Version werfen können genannt werden:

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

BTW: sie verschiedene Namen zu geben, ist keine schlechte Idee. Deshalb haben wir std::cbegin und std::cend in STL.

+0

Danke für die Aufklärung! Dies bedeutet insbesondere, dass jeder Aufruf von 'get_ref' aus der Klasse in die erste (nicht-konstante) Version aufgelöst wird (es sei denn, wir setzen' this' auf "const" ähnlich wie Sie vorgeschlagen haben). Habe ich recht? – PBM

+2

@PBM Genauer gesagt, jeder Aufruf von 'get_ref' aus den Member-Funktionen der Klasse, die Auflösung hängt davon ab, dass 'this' auf 'const' oder 'non-const' zeigt, dh die zuerst aufgerufene Memberfunktion ist 'const' oder nicht. In einer 'const'-Member-Funktion wird also beim Aufruf von' get_ref' die Konstante 'get_ref' aufgerufen; Innerhalb einer nichtkonstanten Memberfunktion wird nicht-const 'get_ref' aufgerufen. – songyuanyao

0

Die Überladungsauflösung betrifft nur die Argumente des Aufrufs (einschließlich des impliziten Arguments für this). Der Ausdruck a.get_ref() muss für die gleiche Überladung ausgewertet werden, unabhängig davon, was mit dem zurückgegebenen Wert geschieht. Das ist grundlegend in C++, und Sie können nichts dagegen tun.

Wenn Sie die const, Qualifizierte Version aufrufen möchten, verwenden Sie einen const, Qualifizierte Objektausdruck:

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

Es gibt natürlich Workaround, basierend auf der konkreten Situation, die Sie behandeln möchten. Wenn Sie angeben, warum Sie ein solches Verhalten wünschen, könnte ich einen Workaround dafür finden. Es wird hässlich und mutlos sein, aber vielleicht möglich. – Angew

Verwandte Themen