मुख्य बिंदु यह है कि protected
आपको में किसी भी अन्य सदस्यों में सदस्यों की अपनी प्रतिलिपि तक पहुंच प्रदान करता है। यह एक आम गलत धारणा है, जितनी बार हम सामान्यीकृत नहीं करते हैं और protected
सदस्य को व्युत्पन्न प्रकार तक पहुंच प्रदान करते हैं (स्पष्ट रूप से केवल अपने स्वयं के आधार पर बताते हुए ...)
अब, यह एक कारण है , और सामान्य रूप से आपको पदानुक्रम की एक अलग शाखा में सदस्य तक नहीं पहुंचना चाहिए, क्योंकि आप उन आविष्कारों को तोड़ सकते हैं जिन पर अन्य वस्तुएं निर्भर करती हैं। एक प्रकार है कि कुछ बड़े डेटा सदस्य (सुरक्षित) और दो व्युत्पन्न प्रकार है कि परिणाम विभिन्न रणनीतियों निम्नलिखित कैश पर एक महंगी गणना करता है पर विचार करें:
class base {
protected:
LargeData data;
// ...
public:
virtual int result() const; // expensive calculation
virtual void modify(); // modifies data
};
class cache_on_read : base {
private:
mutable bool cached;
mutable int cache_value;
// ...
virtual int result() const {
if (cached) return cache_value;
cache_value = base::result();
cached = true;
}
virtual void modify() {
cached = false;
base::modify();
}
};
class cache_on_write : base {
int result_value;
virtual int result() const {
return result_value;
}
virtual void modify() {
base::modify();
result_value = base::result();
}
};
cache_on_read
प्रकार के डेटा में किए गए संशोधन कब्जा और अमान्य के रूप में परिणाम के निशान, ताकि अगले मूल्य पुनर्मूल्यांकन के पढ़े। यह एक अच्छा तरीका है यदि लेखन की संख्या अपेक्षाकृत अधिक है, क्योंकि हम केवल मांग पर गणना करते हैं (यानी कई संशोधित पुनर्मूल्यांकन को ट्रिगर नहीं करेंगे)। cache_on_write
परिणाम को पहले से सटीक करता है, जो कि एक अच्छी रणनीति हो सकती है यदि लेखन की संख्या छोटी है, और आप पढ़ने के लिए निर्धारिती लागत चाहते हैं (पढ़ने पर कम विलंबता सोचें)।
अब, मूल समस्या पर वापस जाएं। दोनों कैश रणनीतियों आधार की तुलना में इनवेरिएंट का एक कठोर सेट बनाए रखते हैं। पहले मामले में, अतिरिक्त आविष्कार यह है कि cached
true
केवल data
अंतिम पढ़ने के बाद संशोधित नहीं किया गया है। दूसरे मामले में, अतिरिक्त आविष्कार यह है कि result_value
हर समय ऑपरेशन का मूल्य है।
तो एक तिहाई व्युत्पन्न प्रकार एक base
के लिए एक संदर्भ लिया और data
पहुँचा लिखने के लिए (यदि protected
यह करने की अनुमति दी), तो यह व्युत्पन्न प्रकार के अपरिवर्तनशीलताओं साथ टूट जाएगा।
कहा जा रहा है कि, भाषा का विनिर्देश टूटा (व्यक्तिगत राय) है क्योंकि यह उस विशेष परिणाम को प्राप्त करने के लिए एक पिछवाड़े छोड़ देता है। विशेष रूप से, यदि आप व्युत्पन्न प्रकार में किसी आधार से किसी सदस्य के सदस्य को पॉइंटर बनाते हैं, तो derived
में एक्सेस की जांच की जाती है, लेकिन लौटा हुआ पॉइंटर base
के सदस्य के लिए एक सूचक है, जिसे परbase
ऑब्जेक्ट पर लागू किया जा सकता है:
class base {
protected:
int x;
};
struct derived : base {
static void modify(base& b) {
// b.x = 5; // error!
b.*(&derived::x) = 5; // allowed ?!?!?!
}
}
@iammilind क्या आप वाकई सही प्रश्न बंद कर रहे हैं? या यह चारों ओर एक और तरीका होना चाहिए? – Eiko
@Eiko मूल रूप से मैंने इस के साथ दूसरे को बंद कर दिया। तब मैंने पाया कि वर्तमान में उत्तर अधिक विस्तृत और मानक के साथ उद्धृत किया गया था। इसलिए इसे फिर से खोल दिया और इसे बंद कर दिया। – iammilind