2017-04-10 6 views
0

Können Sie in diesem Beispielcode aussehen:Rückkehr Bezugnahme auf einen const Zeiger auf const Typen

class Test { 
    int *a; 
    int b; 
public: 
    Test() : b(2) 
    { 
    a = new int(5); 
    } 

    const int * const& GetA() const 
    { 
    const int * const& c = a; 
    return a; 
    } 

    const int& GetB() 
    { 
    return b; 
    } 

    ~Test() 
    { 
    delete a; 
    } 
}; 

Und ich bekomme eine Warnung bei der Rückkehr ein. Warum ist es falsch, einen Verweis auf einen const-Zeiger auf eine const-Variable zurückzugeben, aber es ist in Ordnung, einen Verweis auf eine const-Variable zurückzugeben? By the way, wenn ich c in GetA() zurückgeben, kompiliert es einfach gut.

+3

Welche Warnung erhalten Sie? – NathanOliver

+0

Kann ein Problem nicht auf VS 2015 – alexeykuzmin0

+0

reproduzieren Ich bekomme einen Verweis auf temporäre [-Wreturn-local-addr]. – lepo

Antwort

1

Betrachten Sie zuerst const int& GetB(). Das ist eine nette Möglichkeit, einen Verweis auf das Klassenmitglied b zurückzugeben, das kann nicht an der Aufruf-Website geändert werden. Sie können auch diese Funktion const markieren, da Sie keine Daten der Klassenmitglieder ändern. Dies ist idiomatisches C++, insbesondere für Typen, die größer sind als ein int, z. std::string.

Wenn Sie return a; schreiben, erlauben Sie der Funktionsaufruf-Site, dieses Klassenmitglied über diesen Zeiger zu ändern. Obwohl der C++ - Standard dies zulässt, wird die Kapselung umgangen und Ihr freundlicher Compiler warnt Sie davor. Beachten Sie, dass, da die Funktion selbst ist und nicht den Klassenmember ändert, die Kompilierung ausgeführt wird, obwohl sie als const markiert ist.

Beim Schreiben const int * const& c = a; nimmt der Compiler an, dass Sie wissen, was Sie tun.

(Als abschließende Bemerkung ist alles Chaos los, wenn Sie versuchen, eine Instanz von Test aufgrund der Compiler erzeugt Copykonstruktor seicht-Kopieren a zu kopieren. Sie sollten den Kopierkonstruktor und die Zuweisungsoperatoren delete.)

+0

Dies ist jedoch klar, wenn ich zum Beispiel schreiben 'std :: cout << *(t-> GetA());' Ich bekomme einen segfault. Aber wenn ich zurückkomme, funktioniert der Code gut. – lepo