क्योंकि, जैसा कि बजेर्न ने इसे रखा है, सी ++ मर्फी के खिलाफ रक्षा करने के लिए डिज़ाइन किया गया है, मच्छियाली नहीं।
दूसरे शब्दों में, यह आपको दुर्घटनाओं से बचाने के लिए माना जाता है - लेकिन अगर आप इसे किसी भी काम पर जाने के लिए जाते हैं (जैसे कि कास्ट का उपयोग करना) यह आपको रोकने की कोशिश भी नहीं कर रहा है।
जब मैं इसके बारे में सोचता हूं, तो मेरे मन में कुछ अलग समानता है: यह बाथरूम के दरवाजे पर ताला की तरह है। यह आपको एक चेतावनी देता है कि आप शायद चाहते हैं कि वहां अभी चलें, लेकिन अगर आप निर्णय लेते हैं तो बाहर से दरवाजा अनलॉक करना मुश्किल है।
संपादित करें: प्रश्न के अनुसार @Xeo चर्चा करता है, मानक कहता है कि "सभी सार्वजनिक अभिगम नियंत्रण" के बजाय मानक "समान पहुंच नियंत्रण" क्यों है, जवाब लंबा और थोड़ा कष्टप्रद है।
आइए वापस शुरुआत करने के लिए कदम और की तरह एक struct पर विचार करें:
struct X {
int a;
int b;
};
सी हमेशा इस तरह एक struct के लिए कुछ नियम था। एक यह है कि संरचना के उदाहरण में, संरचना के पते को a
के पते के बराबर होना चाहिए, ताकि आप सूचक को int
पर पॉइंटर पर एक पॉइंटर डालें और अच्छी तरह से परिभाषित परिणामों के साथ a
तक पहुंच सकें। दूसरा यह है कि सदस्यों को स्मृति में उसी क्रम में व्यवस्थित किया जाना चाहिए क्योंकि उन्हें संरचना में परिभाषित किया गया है (हालांकि संकलक उनके बीच पैडिंग डालने के लिए स्वतंत्र है)।
सी ++ के लिए, विशेष रूप से मौजूदा सी structs के लिए बनाए रखने का इरादा था। साथ ही, एक स्पष्ट इरादा था कि यदि संकलक private
(और protected
) को रन-टाइम पर लागू करना चाहता था, तो ऐसा करना आसान होना चाहिए (उचित रूप से कुशलतापूर्वक)।
इसलिए, कुछ दिया की तरह:
struct Y {
int a;
int b;
private:
int c;
int d;
public:
int e;
// code to use `c` and `d` goes here.
};
संकलक Y.a
और Y.b
के संबंध में सी के रूप में ही नियम बनाए रखने के लिए आवश्यक होना चाहिए। इसी समय, अगर यह रन टाइम पर पहुँच लागू करने के लिए जा रहा है, यह स्मृति में एक साथ सभी सार्वजनिक चर ले जाने के लिए इतना लेआउट होगा चाहते हो सकता है और अधिक की तरह:
struct Z {
int a;
int b;
int e;
private:
int c;
int d;
// code to use `c` and `d` goes here.
};
तब, जब उस पर बातें लागू करने है रन-टाइम, यह मूल रूप से if (offset > 3 * sizeof(int)) access_violation();
मेरे ज्ञान के लिए किसी ने कभी ऐसा नहीं किया है, और मुझे यकीन नहीं है कि शेष मानक वास्तव में इसे अनुमति देता है, लेकिन ऐसा लगता है कि कम से कम आधा- उस रेखा के साथ एक विचार के जीवाणु बनाया।
उन दोनों को लागू करने के लिए, सी ++ 98 कहा Y::a
और Y::b
स्मृति में इसी क्रम में होना ही था, और Y::a
struct (अर्थात, सी की तरह नियम) की शुरुआत में होना ही था। लेकिन, हस्तक्षेप पहुंच विनिर्देशकों के कारण, Y::c
और Y::e
अब एक दूसरे के सापेक्ष क्रम में नहीं होना चाहिए था।दूसरे शब्दों में, उनके बीच एक एक्सेस विनिर्देश के बिना परिभाषित सभी लगातार चर को एक साथ समूहीकृत किया गया था, संकलक उन समूहों को पुनर्व्यवस्थित करने के लिए स्वतंत्र था (लेकिन अभी भी शुरुआत में पहले को रखना था)।
यह ठीक था जब तक कि कुछ झटका (यानी, मुझे) ने इंगित किया कि नियमों के लिखे गए तरीके में एक और छोटी समस्या थी। अगर मैंने कोड लिखा:
struct A {
int a;
public:
int b;
public:
int c;
public:
int d;
};
... आप स्वयं के विरोधाभास के साथ समाप्त हो गए। एक ओर, यह अभी भी आधिकारिक तौर पर एक पीओडी संरचना था, इसलिए सी-जैसे नियम लागू किए जाने थे - लेकिन चूंकि आपने सदस्यों के बीच पहुंच विनिर्देशकों (स्वीकार्य रूप से अर्थहीन) थे, इसलिए सदस्यों को पुनर्व्यवस्थित करने के लिए संकलक अनुमति भी दी गई, इस प्रकार सी-जैसे नियमों को तोड़ना उनका इरादा था।
इसे ठीक करने के लिए, उन्होंने मानक को थोड़ा-सा शब्द दिया ताकि यह उन सभी सदस्यों के बारे में बात करे जो सभी के बीच एक समान पहुंच थी या नहीं, बल्कि उनके बीच पहुंच निर्दिष्ट है या नहीं। हां, वे सिर्फ यह कह सकते थे कि नियम केवल सार्वजनिक सदस्यों पर ही लागू होंगे, लेकिन ऐसा लगता है कि किसी ने भी इससे कुछ हासिल नहीं किया था। यह देखते हुए कि यह एक मौजूदा मानक को संशोधित कर रहा था जिसमें बहुत से कोड इस्तेमाल किए गए थे, जो कि छोटे बदलाव के लिए चुना गया था, जो कि अब भी समस्या को ठीक करेगा।
सी ++ में, जिस क्षण आप इसका उपयोग करते हैं, आपने संकलक को बताया है कि आपको इसकी प्रकार की सुरक्षा और जांच की परवाह नहीं है। यह नेटवर्क सुरक्षा नहीं है; यदि आप जोर देते हैं, तो संकलक आपको अपनी खुद की सामग्री को बर्बाद कर देगा, जैसे आपका कोड करता है। – tenfour
@tenfour हाँ मुझे एहसास हुआ कि मैं थोड़ा आश्चर्यचकित था कि यह संभव था। मैंने सी कास्ट को static_cast में बदल दिया और फिर संकलक ने शिकायत की। – mathematician1975
आपको वास्तव में सी ++ में सी कास्ट नहीं करना चाहिए। असल में वे कंपाइलर को 'दूर जाने के बारे में बता रहे हैं, मुझे पता है कि मैं क्या कर रहा हूं, और मैं सभी जिम्मेदारी लेता हूं'। वे reinterpret_cast से भी बदतर हैं (जो भी रास्ते से काम करते थे। Static_cast काम नहीं करेगा क्योंकि आप जो भी पूछ रहे हैं उसे करने के लिए कोई अच्छी तरह से परिभाषित तरीका नहीं है) –