2012-12-13 17 views
6

मैं एक सदस्य चर का उपयोग कर रहा हूं और प्रोग्राम के किसी बिंदु पर मैं इसे बदलना चाहता हूं, लेकिन मैं अनजान परिवर्तनों को रोकने के लिए हर जगह "इसे लॉक" करना पसंद करता हूं।सी ++ में बदलावों को रोकने के लिए एक चर को लॉक किया जा सकता है?

कोड की व्याख्या:

class myClass { 
    int x; // This should be prevented to being changed most of the time 
    int y; // Regular variable 
    myclass() {x = 1;} 
    void foo1() {x++; y++;} // This can change x 
    void foo2() {x--; y--;} // This shouldn't be able to change x 
          // I want it to throw a compile error 
}; 

सवाल है: यह किसी तरह से प्राप्त किया जा सकता है? स्थायी const_cast की तरह कुछ?

मुझे लगता है मैं अभी निर्माता प्रारंभ सूची और निरंतर इस्तेमाल कर सकते हैं पता है, लेकिन मैं बाद में मेरे चर बदलने की जरूरत है।

+2

इसे निजी बनाने, और केवल इसे बदलने आप करना चाहते हैं? – Chad

+0

आप कार्यान्वयन को x को बदलने से रोकना चाहते हैं, या आप किसी को विधि को कॉल करने से रोकना चाहते हैं? – Joe

+0

@ जो: मैं संकलन में इसे एक त्रुटि फेंकना चाहता हूं। – Petr

उत्तर

2

ठीक है, अन्य सभी जवाब मैं नापसंद करते हैं, इसलिए यहाँ मेरा विचार है: चर छिपाना।

#define READONLY(TYPE, VAR) const TYPE& VAR = this->VAR //C++03 
#define READONLY(VARIABLE) const auto& VARIABLE = this->VARIABLE //C++11 

class myClass { 
    int x; // This should be prevented to being changed most of the time 
    int y; // Regular variable 
    myClass() :x(1), y(2) {} 
    void foo1() {// This can change x 
     x++; 
     y++; 
    } 
    void foo2() {// This shouldn't be able to change x 
     READONLY(x); //in this function, x is read-only 
     x++; //error: increment of read-only variable 'x' 
     y++; 
    } 
}; 

अभी भी चर (this->x जैसे) का ताला बायपास करने के लिए तरीके हैं, लेकिन कुछ भी नहीं उन परिस्थितियों के लिए किया जा सकता है।

+0

मुझे लगता है कि यदि आप ऐसा करने जा रहे हैं, तो आपको कुछ चाहिए '# डिफाईन लॉक (v) const auto & v = this-> v', इसलिए फ़ंक्शन में यह' लॉक (x) के रूप में दिखाई देता है;/* ... */'। एक टेम्पलेट आपको वही अधिक साफ करने देता है। –

+0

यह सुरुचिपूर्ण समाधान है यदि मैं केवल एक समारोह में संपादन को रोकना चाहता हूं, लेकिन क्या मैं इसे सामान्य रूप से रोक सकता हूं? – Petr

+1

@ पीटर: सिद्धांत में भी सामान्यीकृत करने का कोई तरीका नहीं है। प्रश्न में आपने _us_ को बताने के लिए टिप्पणियां दी थीं कि कौन से चर लॉक किए गए हैं। कंपाइलर को उसी सामान्य प्रकार की जानकारी की आवश्यकता होगी।_any_ फ़ंक्शन में संपादन योग्य नहीं करना आसान है, लेकिन अगर यह कुछ में संपादन योग्य है, तो आपको हमें/कंपाइलर जो कार्य करना है, उसे बताना होगा। –

0

वैसे आप अपने करने के लिए कोशिश कर रहे हैं ऐसा नहीं कर सकते ... किसी ने मुझे सही कर अगर मैं गलत हूँ।

+1

वह 'foo1', एक्स बदलना चाहता है, लेकिन नहीं' foo2' – Chad

+0

@benjarobin: चर उन्हें –

+0

छुपा बतख @Mooing द्वारा बंद किया जा सकता: लेकिन अगर मैं इसे (जो कि इसका मतलब है) छुपाने के लिए, मैं केवल पढ़ने के लिए इसका इस्तेमाल कर सकते कहीं और उद्देश्य? – Petr

1
class myClass { 
    int x; 
    mutable int y; 
public: 
    myclass() : x(1) {} 
    void foo1() {x++; y++}  // this can change x or y 
    void foo2() const { y--; } // this can't change x by can change y 
}; 

आप इस तरह एक सदस्य समारोह const चिह्नित करते हैं, आपको लगता है कि सदस्य में कुछ भी है कि वस्तु के एक सदस्य को संशोधित करेगा (जब तक कि सदस्य mutable या static है ऐसा नहीं कर सकते हैं - और static वास्तव में नहीं है ऑब्जेक्ट का एक सदस्य बिल्कुल)।

ध्यान दें कि यह आपको ऐसे फ़ंक्शन को कॉल करने से नहीं रोकेगा जो इस तरह के संशोधन करने का प्रयास करता है - बल्कि एक कार्य जो const चिह्नित है लेकिन ऑब्जेक्ट स्थिति को संशोधित करने का प्रयास करता है, बिल्कुल संकलित नहीं होगा।

मैं तथापि, जोड़ना चाहिए, कि मैं बिल्कुल भी विश्वास है कि यह वास्तव में सबसे अच्छा डिजाइन है नहीं कर रहा हूँ। इसके विपरीत दरअसल, यह x पर अपनी आवश्यकताओं की तरह मेरे लिए लग रहा है और y (जैसे, operator= के लिए एक अधिभार है कि केवल सही तहत इनपुट स्वीकार करता है प्रदान करके पर्याप्त जटिल है कि वे शायद अलग वर्ग है कि उचित की कमी को सीधे लागू रूप में और अधिक समझ बनाने चाहते हैं परिस्थितियों)।

दूसरे शब्दों में, mutable के उपयोग मैं ऊपर दिखाए गए है (मुझे लगता है कि) सवाल का सरल और सबसे सीधा जवाब आपके द्वारा पूछे गए, लेकिन यह काफी संभवतया ऐसा प्रतीत होता है कि आप नहीं कर रहे हैं वास्तव में पूछ सवाल जो आपको करना चाहिए, और डिजाइन को बदलने से आपको लाभ होने की अधिक संभावना है - दुर्भाग्य से, आपने हमें "बड़ी तस्वीर" के बारे में पर्याप्त जानकारी नहीं दी है ताकि यह सुझाव दिया जा सके कि बेहतर डिज़ाइन क्या हो सकता है।

+0

@MooingDuck: धन्यवाद। अपडेट किया गया। –

+0

'mutable'? मुझे लगता है कि मैंने 'कॉन्स' विचार छोड़ दिया होगा और व्यक्तिगत रूप से वेरिएबल को छिपाने के साथ चला गया होगा। या यूनिट परीक्षण या कुछ। –

+1

@MooingDuck: वह जो पूछ रहा है उसका सबसे सीधा जवाब है। मुझे लगता है कि मुझे थोड़ी सी चेतावनी जोड़नी चाहिए। –

1

ठीक है, मैं यह, अपने प्रयास के लायक है वैसे भी, अगर इस क्विज या sth है, दोस्त के साथ निजी वंशानुक्रम गठबंधन करने के लिए कोशिश यकीन नहीं है:

class MyClassX { 
protected: 
    MyClassX() : x(1) {} 
    int x; 
public: 
    int getX() const { return x; } // read only access 
}; 
class MyClassY { 
protected: 
    MyClassY() : y(0) {} 
    int y; 
    friend class MyClass; 
public: 
    int getY() const { return y; } 
}; 
class MyClassXY : private MyClassX, private MyClassY { 
public: 
    void foo1() {x++; y++}  // this can change x or y 
}; 
MyClass : public MyClassXY { 
public: 
    void foo2() const { y--; } // this can't change x but can change y 
}; 
+0

कोई परीक्षण नहीं, लेकिन बस मेरी जिज्ञासा। – Petr

+0

@ पीटर - मैंने अपना समाधान नहीं देखा, अगर मुझे ठीक करने के लिए कुछ पता है तो मुझे बताएं। मेरे सर्वोत्तम ज्ञान के अनुसार इसे आपकी बाधाओं को पूरा करना चाहिए। जिज्ञासा के लिए – PiotrNycz

+0

@ पीटर (+1), मुझे हमेशा विश्वास है कि यह अच्छी बात है। – PiotrNycz

0

तकनीकी तौर पर, जवाब नहीं है, के रूप में लंबे समय तक कक्षा चर देख सकती है और यह स्थिर नहीं है - यह इसे संशोधित कर सकती है। लेकिन आप जो वैरिएबल चाहते हैं उसे पूरा कर सकते हैं जिसे आप एक अलग वर्ग में लॉक करना चाहते हैं।

0

एक निजी एक्स चर के साथ एक कक्षा बनाएँ। इसमें अपनी विधि लिखें।

इस कक्षा से अपनी वास्तविक कक्षा प्राप्त करें। एक्स धारक को वास्तविक वर्ग का मित्र बनाओ।

एक्स धारक एक्स धारक में कास्टिंग (आधार करने के लिए स्थिर डाली) अपने वास्तविक वर्ग के लिए एक सूचक में इस बारी करने की तरह CRTP उपयोग करता है।

अपने एक्स धारक से एक एक्स गेटटर का पर्दाफाश करें।

मैं अपने आप को परेशान नहीं होगा, लेकिन यह अस्थायी और स्थिरांक कोस से बेहतर है।

1

x एक subClass के private सदस्य है, और foo1 बनाने subClass के एक दोस्त समारोह। इस तरह:

class myClass { 
    int y; // Regular variable 
    myClass() : x (1) {} 
    void foo1() {x.x++; y++;} // This can change x 
    void foo2() {x.x--; y--;} // This shouldn't be able to change x 
          // I want it to throw a compile error 
    class subClass { 
     friend void myClass::foo1() ; // This must come after the declaration of foo1 
     int x ; // private 
    public: 
     subClass (int x) : x (x) { } 
     int read_x() const { return x ; } 
     } x ; 
}; 

यह एक कंपाइलर त्रुटि फेंकता है, जहां आप इसे चाहते थे।

+0

मुझे उलझन में आया क्योंकि आपने कभी भी 'read_x' का उपयोग नहीं किया है, लेकिन आप सही हैं: http://ideone.com/JTkfSq –

+0

@Mooing Duck: केवल एक लिखने वाला चर क्या उपयोग है? – TonyK

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

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