2012-12-06 4 views
6

Zum Beispiel:Ist es in Ordnung, const-Qualifikationsmerkmal zu entfernen, wenn der Aufruf von derselben nicht-const-Version überladenen Mitgliedsfunktion stammt?

struct B{}; 

struct A { 

const B& findB() const { /* some non trivial code */ } 

// B& findB() { /* the same non trivial code */ } 

B& findB() { 
     const A& a = *this; 
     const B& b = a.findB(); 
     return const_cast<B&>(b); 
    } 
}; 

Die Sache ist, ich die gleiche Logik Wiederholung innerhalb des konstanten FINDENB und nicht konstanter FINDENB Memberfunktion zu vermeiden.

+0

Es scheint, dass Sie wie Referenzen viel. –

+0

Kein Punkt in der Verwendung von Zeigern oder Kopien, wenn nicht benötigt – dchhetri

Antwort

7

Ja, Sie das Objekt const werfen können, rufen Sie die const Version, warf dann das Ergebnis const auf nicht:

return const_cast<B&>(static_cast<const A*>(this)->findB()); 

Casting weg const sicher ist nur, wenn das betreffende Objekt war ursprünglich nicht erklärt const. Da Sie sich in einer Member-Funktion befinden, die nicht in der const ist, können Sie wissen, dass dies der Fall ist, aber es hängt von der Implementierung ab. Überlegen Sie:

class A { 
public: 

    A(int value) : value(value) {} 

    // Safe: const int -> const int& 
    const int& get() const { 
     return value; 
    } 

    // Clearly unsafe: const int -> int& 
    int& get() { 
     return const_cast<int&>(static_cast<const A*>(this)->get()); 
    } 

private: 
    const int value; 
}; 

Im Allgemeinen sind meine Mitgliedsfunktionen kurz, so dass die Wiederholung tolerierbar ist. Sie können die Implementierung manchmal in eine private Template-Member-Funktion einbeziehen und diese aus beiden Versionen aufrufen.

+2

"Da Sie in einer nicht-const-Methode sind, wissen Sie, dass dies der Fall ist." Was meinen Sie? Eine Nicht-Const-Methode kann sehr gut ein Const-Objekt zurückgeben. –

+2

Wenn Sie eine private Hilfsfunktion haben und es sich nicht um eine const-Member-Funktion handelt, wie kann ich dann von der const-Version aus aufrufen, ohne die Konstante zu entfernen? Wie könnte ich diese nicht-konstante private Hilfsfunktion von der konstanten öffentlichen Elementfunktion aufrufen. Würde es sich immer noch über die Beständigkeit beschweren? – dchhetri

1

Ich denke, dass hier werfen Verwendung ist in Ordnung, aber wenn man es auf jeden Fall vermeiden wollen, können Sie einige Vorlage Magie:

struct B 
{ 
    B(const B&) 
    { 
     std::cout << "oops I copied"; 
    } 
    B(){} 
}; 

struct A { 
public: 
    A(){} 
    A(const A&){ std::cout << "a is copied:(\n";} 
    const B& findB() const { return getter(*this); }  
    B& findB() { return getter(*this); } 

private: 
    template <typename T, typename V> 
    struct same_const 
    { 
     typedef V& type; 
    }; 

    template <typename T, typename V> 
    struct same_const<const T, V> 
    { 
     typedef const V& type; 
    }; 

    template <typename T> 
    static typename same_const<T,B>::type getter(T& t) { return t.b;} 

    B b; 

}; 

int main() 
{ 
    A a; 
    const A a_const; 
    const B& b1 = a.findB(); 
    B& b2 = a.findB(); 

    const B& b3 = a_const.findB(); 
    //B& b4 = a_const.findB(); 
} 
+0

Woah cool Trick, aber das ist übertrieben und würde die Dinge meiner Meinung nach viel schlimmer machen. – dchhetri

+0

@ user814628, stimme ich zu, nur wollte es funktionieren. – Lol4t0

Verwandte Themen