2012-12-06 7 views
6

उदाहरण के लिए:जब कॉल एक ही गैर-कॉन्स संस्करण अधिभारित सदस्य फ़ंक्शन से होता है तो कॉन्स्ट क्वालीफायर को निकालना ठीक है?

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

बात मैं लगातार findB और गैर निरंतर findB सदस्य समारोह के अंदर एक ही तर्क दोहराने से बचें करना चाहते हैं।

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

दूर कास्टिंग const सुरक्षित है केवल जब प्रश्न में वस्तु मूल रूप से घोषित नहीं किया गया था:

+0

यह एक बहुत संदर्भ की तरह आप लगता है। –

+0

पॉइंटर्स या प्रतियों का उपयोग करने में कोई बिंदु नहीं है यदि आवश्यक नहीं है – dchhetri

उत्तर

7

हाँ, आप const करने के लिए वस्तु डाल सकता, const संस्करण कहते हैं, तो const गैर करने के लिए परिणाम डाली const। चूंकि आप गैर-const सदस्य फ़ंक्शन में हैं, इसलिए आप इसे केस के रूप में जान सकते हैं, लेकिन यह कार्यान्वयन पर निर्भर करता है। विचार करें:

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

आम तौर पर, मेरे सदस्य कार्य कम होते हैं, इसलिए पुनरावृत्ति सहनशील होती है। आप कभी-कभी किसी निजी टेम्पलेट सदस्य फ़ंक्शन में कार्यान्वयन को कारक बना सकते हैं और दोनों संस्करणों से कॉल कर सकते हैं।

+2

"चूंकि आप एक गैर-कॉन्स विधि में हैं, तो आप इसे इस मामले के बारे में जानते हैं।" आपका मतलब क्या है? एक गैर-'const' विधि 'const' ऑब्जेक्ट को बहुत अच्छी तरह से वापस कर सकती है। –

+2

यदि आपके पास एक निजी सहायक कार्य है, और यह एक कॉन्स्ट-सदस्य फ़ंक्शन नहीं है, तो मैं निरंतरता को हटाए बिना इसे कॉन्स्ट-संस्करण से कैसे कॉल कर सकता हूं? निरंतर सार्वजनिक सदस्य समारोह से मैं उस गैर-निरंतर निजी सहायक फ़ंक्शन को कैसे कॉल कर सकता हूं। क्या यह अभी भी इसकी निरंतरता के बारे में शिकायत नहीं करेगा? – dchhetri

1

मुझे लगता है, कि यहां डाली का उपयोग ठीक है, लेकिन अगर आप निश्चित रूप से इसे से बचना चाहते हैं, तो आपको कुछ टेम्पलेट जादू का उपयोग कर सकते हैं:

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

वाह कूल चाल, लेकिन यह अधिक है और मेरी राय में चीजों को और भी बदतर बना देगा। – dchhetri

+0

@ user814628, मैं सहमत हूं, बस इसे काम करना चाहता था। – Lol4t0