एक कास्ट पॉइंटर अत्यधिक लागू होने का एक उदाहरण इस प्रकार प्रदर्शित किया जा सकता है। विचार करें कि आपके पास एक गतिशील सरणी के साथ एक वर्ग है, और आप उपयोगकर्ता को सरणी तक पहुंच देना चाहते हैं, लेकिन उन्हें सूचक को बदलने के अधिकार दिए बिना। विचार करें:
#include <new>
#include <string.h>
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const GetArray(){ return Array; }
};
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' '; //You can still modify the chars in the array, user has access
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
}
जो पैदा करता है:
इनपुट डेटा
डाल डेटा
लेकिन अगर हम यह कोशिश करें:
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' ';
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
Temp.GetArray() = NULL; //Bwuahahahaa attempt to set it to null
}
हमें मिला:
त्रुटि: असाइनमेंट के बाएं ऑपरेंड के रूप में आवश्यक अंतराल // Drat फिर से नाकाम!
तो स्पष्ट रूप से हम सरणी की सामग्री को संशोधित कर सकते हैं, लेकिन सरणी के सूचक को नहीं। यदि आप यह सुनिश्चित करना चाहते हैं कि उपयोगकर्ता के पास वापस जाते समय सूचक के पास एक सुसंगत स्थिति है। हालांकि एक कैच है:
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' ';
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
delete [] Temp.GetArray(); //Bwuahaha this actually works!
}
हम अभी भी पॉइंटर की मेमोरी रेफरेंस को डिलीट कर सकते हैं, भले ही हम पॉइंटर को खुद ही संशोधित नहीं कर सकते।
इसलिए यदि आप चाहते हैं कि मेमोरी रेफरेंस हमेशा किसी चीज़ की ओर इशारा करे (IE को कभी संशोधित नहीं किया जाए, तो वर्तमान में कैसा रेफरेंस काम करता है), तो यह अत्यधिक लागू होता है। यदि आप चाहते हैं कि उपयोगकर्ता की पूरी पहुँच हो और इसे संशोधित किया जाए, तो नॉन-कास्ट आपके लिए है।
संपादित करें:
GetArray के कारण असाइन नहीं होने की टिप्पणी okorz001 नोट करने के बाद () एक राइट-वैल्यू ऑपरेंड होने के कारण, उनकी टिप्पणी पूरी तरह से सही है, लेकिन उपरोक्त अभी भी लागू होता है यदि आप पॉइंटर का एक संदर्भ वापस करना चाहते थे (मुझे लगता है कि GetArray था उदाहरण के लिए)
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const &GetArray(){ return Array; } //Note & reference operator
char * &GetNonConstArray(){ return Array; } //Note non-const
};
int main()
{
TestA Temp;
Temp.GetArray() = NULL; //Returns error
Temp.GetNonConstArray() = NULL; //Returns no error
}
पहले एक त्रुटि के परिणामस्वरूप वापस आएगा:
त्रुटि: केवल-पढ़ने के लिए स्थान 'Temp.TestA :: GetArray ()'
लेकिन दूसरा नीचे की ओर संभावित परिणामों के बावजूद पूरी तरह से घटित होगा।
जाहिर है, सवाल उठाया जाएगा कि 'आप एक पॉइंटर का संदर्भ क्यों लौटाना चाहेंगे'? ऐसे दुर्लभ उदाहरण हैं जहां आपको प्रश्न में सीधे मूल सूचक को मेमोरी (या डेटा) निर्दिष्ट करने की आवश्यकता होती है (उदाहरण के लिए, अपना स्वयं का मॉलोक / मुक्त या नया / मुक्त फ्रंट-एंड बनाना), लेकिन उन उदाहरणों में यह एक गैर-कॉन्स्टेंस संदर्भ है । एक कास्ट पॉइंटर का संदर्भ मैं ऐसी स्थिति में नहीं आया हूं जो इसे वारंट करेगा (जब तक कि रिटर्न प्रकारों की तुलना में घोषित कॉन्स्ट रेफरेंस वैरिएबल?) नहीं होगा।
विचार करें कि क्या हमारे पास एक फ़ंक्शन है जो एक कॉन्स्टेंट पॉइंटर लेता है (बनाम जो ऐसा नहीं करता है):
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const &GetArray(){ return Array; }
void ModifyArrayConst(char * const Data)
{
Data[1]; //This is okay, this refers to Data[1]
Data--; //Produces an error. Don't want to Decrement that.
printf("Const: %c\n",Data[1]);
}
void ModifyArrayNonConst(char * Data)
{
Data--; //Argh noo what are you doing?!
Data[1]; //This is actually the same as 'Data[0]' because it's relative to Data's position
printf("NonConst: %c\n",Data[1]);
}
};
int main()
{
TestA Temp;
Temp.ModifyArrayNonConst("ABCD");
Temp.ModifyArrayConst("ABCD");
}
इस प्रकार संदेश में त्रुटि का कारण बनता है:
त्रुटि: रीड-ओनली पैरामीटर 'डेटा' का घटाव
यह अच्छा है क्योंकि हम शायद ऐसा नहीं करना चाहते हैं, जब तक कि हम टिप्पणियों में बताई गई समस्याओं का कारण नहीं बनना चाहते। अगर हम कास्ट फंक्शन में कमी को संपादित करते हैं, तो निम्न होते हैं:
नॉनकॉन्स्ट: ए कांस्ट:
बी
स्पष्ट रूप से, भले ही ए 'डेटा [1]' है, इसे 'डेटा [0]' के रूप में माना जा रहा है, क्योंकि नॉनकॉस्ट पॉइंटर ने वेतन वृद्धि के संचालन की अनुमति दी थी। लागू किए गए कॉन्स्ट के साथ, जैसा कि एक अन्य व्यक्ति लिखता है, हम संभावित बग को होने से पहले पकड़ लेते हैं।
एक अन्य मुख्य विचार, यह है कि एक कास्ट पॉइंटर को एक छद्म संदर्भ के रूप में इस्तेमाल किया जा सकता है, इस बात में कि संदर्भ बिंदुओं को बदला नहीं जा सकता है (एक चमत्कार, यदि शायद यह कैसे लागू किया गया था)। विचार करें:
int main()
{
int A = 10;
int * const B = &A;
*B = 20; //This is permitted
printf("%d\n",A);
B = NULL; //This produces an error
}
संकलन करने का प्रयास करते समय, निम्न त्रुटि उत्पन्न करता है:
त्रुटि: केवल-पढ़ने के लिए परिवर्तनशील 'B'
यदि ए को एक निरंतर संदर्भ चाहिए था तो यह संभवतः एक बुरी बात है। यदि B = NULLटिप्पणी की जाती है, तो संकलक हमें खुशी से संशोधित करेगा *Bऔर इसलिए ए। यह ints के साथ उपयोगी नहीं लग सकता है, लेकिन विचार करें कि क्या आपके पास ग्राफ़िकल एप्लिकेशन का एक भी रुख है जहां आप एक अपरिवर्तनीय पॉइंटर चाहते थे जो इसे संदर्भित करता है - जिसे आप पास कर सकते हैं चारों ओर।
यह उपयोग परिवर्तनशील है (अनजाने वाक्य को बहाना), लेकिन सही ढंग से उपयोग किया जाता है, यह प्रोग्रामिंग के साथ सहायता करने के लिए बॉक्स में एक और उपकरण है।