2010-03-26 13 views
5

एक सहकर्मी ने इस तरह के कुछ कोड के बारे में पूछा जो मूल रूप से इसमें टेम्पलेट था।मैं एक कॉन्स्ट विधि से गैर-कॉन्स्ट सदस्य फ़ंक्शन पॉइंटर क्यों कॉल कर सकता हूं?

मैंने टेम्पलेट हटा दिए हैं, लेकिन मूल प्रश्न बना हुआ है: यह ठीक क्यों संकलित करता है?

#include <iostream> 

class X 
{ 
public: 
    void foo() { std::cout << "Here\n"; } 
}; 

typedef void (X::*XFUNC)() ; 

class CX 
{ 
public: 
    explicit CX(X& t, XFUNC xF) : object(t), F(xF) {}  
    void execute() const { (object.*F)(); } 
private: 
    X& object; 
    XFUNC F; 
}; 

int main(int argc, char* argv[]) 
{ 
    X x; 
    const CX cx(x,&X::foo); 
    cx.execute(); 
    return 0; 
} 

यह देखते हुए कि CX एक स्थिरांक वस्तु है, और उसके सदस्य समारोह निष्पादित स्थिरांक है CX अंदर इसलिए :: निष्पादित इस सूचक स्थिरांक है।

लेकिन मैं सदस्य फ़ंक्शन पॉइंटर के माध्यम से एक गैर-कॉन्स्ट सदस्य फ़ंक्शन को कॉल करने में सक्षम हूं।

सदस्य फ़ंक्शन पॉइंटर्स दुनिया के कॉन्स्टेस में एक दस्तावेज छेद पॉइंटर्स हैं?

क्या (दूसरों के लिए संभवतः स्पष्ट) मुद्दे क्या हमने याद किया है?

उत्तर

7

इस संदर्भ object में एक एक स्थिरांक X करने के लिए एक X, नहीं एक संदर्भ के संदर्भ में है। const क्वालीफायर सदस्य (यानी संदर्भ के लिए लागू किया जाएगा, लेकिन संदर्भ const नहीं हो सकता है), संदर्भित ऑब्जेक्ट पर नहीं।

// ... 
private: 
    X object; 
// ... 

आप त्रुटि आप उम्मीद कर रहे हैं मिलता है:

आप अपने वर्ग परिभाषा को बदलते हैं एक संदर्भ का उपयोग नहीं करने के लिए।

+0

फिर भी, 'const'-विधियों के साथ किसी को केवल सदस्य-वस्तुओं पर' const 'विधियों को कॉल करने में सक्षम होना चाहिए, है ना? –

+3

सदस्य संदर्भ है, संदर्भित वस्तु नहीं। –

7

constexecute() की नस्ल केवल कक्षा के this सूचक को प्रभावित करता है। यह T* के बजाय thisconst T* का प्रकार बनाता है। यह यद्यपि 'गहरा' नहीं है - इसका मतलब केवल सदस्यों को ही बदला नहीं जा सकता है, लेकिन वे जो कुछ भी इंगित करते हैं या संदर्भ अभी भी कर सकते हैं। आपका object सदस्य पहले से ही बदला नहीं जा सकता है, क्योंकि संदर्भ किसी और चीज को इंगित करने के लिए फिर से बैठे नहीं जा सकते हैं। इसी तरह, आप सिर्फ एक सदस्य समारोह सूचक के रूप में यह अपसंदर्भन नहीं बदल रहा F सदस्य हैं, इसलिए। तो यह सब अनुमति है, और ठीक है।

तथ्य यह है कि आप CX स्थिरांक के अपने उदाहरण कुछ भी नहीं बदलता है बनाने: फिर, कि तत्काल सदस्य नहीं संशोधित करने की अनुमति दी जा रही है को संदर्भित करता है, लेकिन फिर से कुछ भी वे बात करने के लिए अभी भी कर सकते हैं। आप अभी भी कॉन्स्ट ऑब्जेक्ट्स पर कॉन्स्ट सदस्य फ़ंक्शन कॉल कर सकते हैं ताकि वहां कोई बदलाव न हो।

इसे समझने के लिए:

class MyClass 
{ 
public: 
    /* ... */ 

    int* p; 

    void f() const 
    { 
     // member p becomes: int* const p 
     *p = 5; // not changing p itself, only the thing it points to - allowed 
     p = NULL; // changing content of p in const function - not allowed 
    } 
}; 
+1

यह ध्यान रखना महत्वपूर्ण है कि आप मूल रूप से 'टी' और 'टी * कॉन्स' के रूप में व्यवहार कर सकते हैं। वैसे भी मैं मानता हूं कि 'const' का उथला-प्रचार अजीब है, लेकिन फिर हमारे पास डिफ़ॉल्ट रूप से उथली प्रतिलिपि भी है ... –

3

उदाहरण class X की object स्थिरांक नहीं है। यह केवल एक वस्तु जो स्थिरांक है द्वारा संदर्भित है। कॉन्स्ट सत्ता रिकर्सिवली subobjects पर लागू होता है, संदर्भित वस्तुओं के लिए नहीं।

वैकल्पिक तर्क से, const विधि कुछ भी संशोधित करने में सक्षम नहीं होगी। यही कारण है कि एक "शुद्ध समारोह," एक अवधारणा है जो वर्तमान मानक सी ++ में मौजूद नहीं है कहा जाता है।

1

आप foo पर object पर कॉल कर रहे हैं, this पर नहीं।

object के बाद आप उस पर गैर स्थिरांक तरीकों कॉल करने के लिए अनुमति देता है (जो const X& के समान नहीं है) एक निरंतर CX में, यह वास्तव में एक X& const है एक X& के रूप में घोषित किया गया है।

+0

मुझे लगता है कि आपको" एक्स एंड कॉन्स्ट "का उल्लेख होना चाहिए था, क्योंकि लंगेज में गैर-संवेदनात्मक है, क्योंकि वहां है 'संदर्भ पुनः बाध्यकारी' जैसी कोई चीज़ नहीं है। –

0

इसके बारे में सोचने का एक उपयोगी तरीका यह हो सकता है कि आपका एक्स ऑब्जेक्ट सीएक्स का सदस्य न हो।

+0

आप इस तरह के बारे में सोच सकते हैं, लेकिन इससे कोई फर्क नहीं पड़ता कि यह है या नहीं। उस वर्ग में एक एक्स उदाहरण ('ऑब्जेक्ट') सदस्य के रूप में और संदर्भ के लिए एक संदर्भ सदस्य भी हो सकता है। फिर आप पाएंगे कि आप '(ऑब्जेक्ट। * एफ)();' 'नहीं कर सकते हैं, लेकिन अभी भी '(संदर्भ। * एफ)(); * हो सकता है; भले ही यह सटीक वही बात करता है जो ** है ** सीएक्स का एक सदस्य। – UncleBens

संबंधित मुद्दे