एक स्थैतिक सदस्य एक स्थैतिक डेटा सदस्य को क्यों बदल सकता है?


86

निम्नलिखित C++कार्यक्रम में, एक फ़ंक्शन से एक स्थिर डेटा सदस्य को संशोधित constकरना ठीक काम कर रहा है:

class A 
{
  public:   
    static int a; // static data member

    void set() const
    {
        a = 10;
    }
};

लेकिन एक फ़ंक्शन से एक गैर-स्थैतिक डेटा सदस्य को संशोधित constकरना काम नहीं करता है:

class A 
{
  public:   
    int a; // non-static data member

    void set() const
    {
        a = 10;
    }
};

कोई constसदस्य फ़ंक्शन staticडेटा सदस्य को संशोधित क्यों कर सकता है ?


यह उपयोगी होगा यदि आप हमें बता सकते हैं कि आप किस मंच और संकलक के साथ काम कर रहे हैं? तो हम यह निर्धारित कर सकते हैं कि क्या व्यवहार आपके विशिष्ट सेटअप से संबंधित बग है या यदि व्यवहार वास्तव में सही है और बस समझाने की आवश्यकता है।
एलेक्स ज़ीविकि

लिनक्स प्लेटफॉर्म पर @AlexZywicki G ++ कंपाइलर।
एमएससी

8
कोई जरुरत नहीं है। यह जानबूझकर है और सभी C ++ कंपाइलरों को इसका समर्थन करना चाहिए। लेकिन इस तरह के अच्छे सवाल क्यों नहीं उठाए गए?
बाथशीबा

18
यह एक द्वैध है, लेकिन यह एक बेहतर MCVE के लिए अन्य धन्यवाद की तुलना में बेहतर लिखा गया है, इसलिए मैंने इसे लक्ष्य के रूप में उपयोग किया।
बौम Augen mit

5
यहाँ प्रेरणा का constअर्थ है कि किसी वस्तु का सदस्य कार्य उस एक वस्तु को संशोधित नहीं कर सकता है । यह उसी वर्ग, या staticडेटा की अन्य वस्तुओं को संशोधित कर सकता है , जो वर्ग से जुड़ा है, इसका कोई विशेष उदाहरण नहीं। (या mutableडेटा सदस्य, जो इस नियम के अपवाद के रूप में बनाए गए थे।)
डेविस्लोर

जवाबों:


100

यह नियम है, बस। और अच्छे कारण के लिए।

constएक सदस्य समारोह का मतलब है कि आप गैर संशोधित नहीं कर सकते पर क्वालीफायर mutableगैर staticवर्ग सदस्य चर।

कुछ युक्तिकरण की पेशकश के माध्यम से, thisएक constयोग्य सदस्य फ़ंक्शन में सूचक एक constप्रकार है, और thisस्वाभाविक रूप से एक वर्ग के उदाहरण से संबंधित है । staticसदस्य वर्ग के उदाहरण से संबंधित नहीं हैं। आपको एक staticसदस्य को संशोधित करने के लिए एक उदाहरण की आवश्यकता नहीं है : आप इसे अपने मामले में, लिखकर कर सकते हैं A::a = 10;

तो, अपने पहले मामले में, के a = 10;लिए शॉर्टहैंड के रूप A::a = 10;में और दूसरे मामले में, इसके लिए शॉर्टहैंड के रूप में सोचें this->a = 10;, जो कि प्रकार के बाद से अनिवार्य नहीं thisहै const A*


1
बस यहाँ एक मामूली त्रुटि: जब से तुम पुन: असाइन नहीं कर सकते thisसूचक है, यह प्रकार का होगा const A* const में constहै मामला।
टेलर हेन्सन

2
@TaylorHansen thisपॉइंटर टाइप का एक प्रचलन है। गैर-वर्ग-प्रकार के सिद्धांत कभी भी सीवी-योग्य नहीं होते हैं।

21

सी ++ मानक के अनुसार (9.2.3.2 स्टेटिक डेटा सदस्य)

1 एक स्थैतिक डेटा सदस्य किसी वर्ग के उप-अंशों का हिस्सा नहीं है ...

और (9.2.2.1 यह सूचक)

1 एक गैर-स्थैतिक (9.2.1) सदस्य फ़ंक्शन के शरीर में, यह एक प्रचलित अभिव्यक्ति है जिसका मूल्य उस वस्तु का पता है जिसके लिए फ़ंक्शन कहा जाता है। एक कक्षा X के सदस्य फ़ंक्शन में इसका प्रकार X * है। यदि सदस्य फ़ंक्शन को const घोषित किया जाता है, तो इसका प्रकार const X * है , ...

और अंत में (9.2.2 गैर-स्थैतिक सदस्य कार्य)

3 ... यदि नाम लुकअप (3.4) कुछ कक्षा C के गैर-स्थिर गैर-प्रकार के सदस्य के लिए आईडी-एक्सप्रेशन में नाम को हल करता है, और यदि या तो आईडी-एक्सप्रेशन का संभावित मूल्यांकन किया गया है या C X या बेस क्लास है X का, आईडी-एक्सप्रेशन-अभिव्यक्ति (5.2.5) एक क्लास मेंबर एक्सप्रेशन (5.2.5) का उपयोग करके (* यह) (9.2.2.1) के रूप में बदल दिया जाता है, जो बाईं ओर पोस्टफिक्स-एक्सप्रेशन है। ऑपरेटर।

इस प्रकार इस वर्ग की परिभाषा में

class A 
{
  public:   
    static int a; 

    void set() const
    {
        a = 10;
    }
};

स्थैतिक डेटा सदस्य aवर्ग प्रकार के ऑब्जेक्ट का उप-विषय thisनहीं है और स्थिर डेटा सदस्य तक पहुंचने के लिए पॉइंटर का उपयोग नहीं किया जाता है। इसलिए कोई भी सदस्य फ़ंक्शन, गैर-स्थिर स्थिरांक या गैर-स्थिर, या एक स्थैतिक सदस्य फ़ंक्शन डेटा सदस्य को बदल सकता है क्योंकि यह एक स्थिर नहीं है।

इस वर्ग की परिभाषा में

class A 
{
  public:   
    int a; 

    void set() const
    {
        a = 10;
    }
};

गैर-स्थैतिक डेटा सदस्य aवर्ग प्रकार के ऑब्जेक्ट का एक उप-विषय है। किसी सदस्य फ़ंक्शन में इसे एक्सेस करने के लिए या तो उपयोग किया जाता है या इस सिंटैक्स के एक सदस्य एक्सेस सिंटैक्स निहित है। thisडेटा सदस्य को संशोधित करने के लिए आप निरंतर सूचक का उपयोग नहीं कर सकते हैं । और सूचक यह वास्तव में const A *फ़ंक्शन के भीतर प्रकार है setक्योंकि फ़ंक्शन को क्वालीफायर के साथ घोषित किया गया है const। यदि फ़ंक्शन में इस मामले में कोई क्वालीफायर नहीं था, तो डेटा सदस्य को बदला जा सकता है।


13

बात यह है, कि यदि किसी वर्ग Aका सदस्य कार्य करता है const, तो वह प्रकार thisहै const X*, और इस तरह गैर-स्थैतिक डेटा सदस्यों को परिवर्तित होने से रोकता है (cf, उदाहरण के लिए, C ++ मानक ):

9.3.2 यह सूचक [class.this]

एक गैर-स्थैतिक (9.3) सदस्य फ़ंक्शन के शरीर में, यह कीवर्ड एक प्रचलित अभिव्यक्ति है जिसका मूल्य उस ऑब्जेक्ट का पता है जिसके लिए फ़ंक्शन कहा जाता है। एक कक्षा X के सदस्य फ़ंक्शन में इसका प्रकार X * है। यदि सदस्य फ़ंक्शन को const घोषित किया जाता है, तो इसका प्रकार const X * है, ...

यदि aकोई गैर-स्थैतिक डेटा सदस्य है, तो a=10जैसा है वैसा ही है this->a = 10, जिसे अनुमति नहीं दी गई thisहै const A*और aनहीं के रूप में घोषित किया गया है mutable। इस प्रकार, चूंकि होने void set() constका प्रकार बनाता है , इसलिए इस पहुंच की अनुमति नहीं है।thisconst A*

यदि aइसके विपरीत एक स्थिर डेटा सदस्य है, तो a=10इसमें बिल्कुल भी शामिल नहीं है this; और जब तक static int aस्वयं द्वारा घोषित नहीं किया जाता है const, तब तक कथन a=10की अनुमति है।


1

constएक पर क्वालीफायर सदस्य समारोह का मतलब है कि आप संशोधित नहीं कर सकते non-mutable, non-static वर्ग डेटा सदस्यों

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.