2013-03-21 10 views
5

मुझे पता है कि मैं एक वर्ग या struct लेकिन निम्न कोड की अंतिम पंक्ति के लिए डेटा सदस्य के लिए एक सूचक प्राप्त कर सकते हैं संकलित करने के लिए विफल रहता है:Convert सूचक शून्य करने के लिए *

struct abc 
{ 
    int a; 
    int b; 
    char c; 
}; 

int main() 
{ 
    typedef struct abc abc; 
    char abc::*ptt1 = &abc::c; 
    void *another_ptr = (void*)ptt1; 
} 

क्यों नहीं कर सकते हैं मैं ptt1 को दूसरे_ptr में परिवर्तित करता हूं? हम संकेत के बारे में बात कर रहे हैं तो एक सूचक एक और एक करने के लिए एक समान आयाम होना चाहिए (हालांकि धारणात्मक अलग)

+0

त्रुटि संदेश क्या है? –

+1

"टाइपपीफ स्ट्रक्चर एबीसी एबीसी;" वास्तव में? –

+0

मैं MSVC2012 का उपयोग कर रहा हूं: त्रुटि C2440: 'टाइप कास्ट': 'char abc :: *' से 'void *' में परिवर्तित नहीं हो सकता – Paul

उत्तर

9

गैर स्थिर वर्ग के सदस्य प्रकार के लिए एक सूचक एक वस्तु सूचक प्रकार के रूप में ही नहीं है, वे बहुत अलग व्यवहार करते हैं। असल में, आप * के साथ सदस्य को पॉइंटर को भी कम नहीं कर सकते हैं। सदस्य को पॉइंटर के माध्यम से किसी सदस्य तक पहुंचने के लिए, आप इसके बजाय .* और ->* ऑपरेटरों का उपयोग करते हैं। यदि आप इसे ऑब्जेक्ट पॉइंटर प्रकार में डाल सकते हैं, तो क्या होगा, फिर, यदि आपने * के साथ इसे संदर्भित किया है?

केवल वस्तु सूचक प्रकार void* करने के लिए एक मानक रूपांतरण (§4.10) है:

प्रकार का एक prvalue "सूचक सीवीTके लिए," जहां T एक वस्तु प्रकार है, एक करने के लिए परिवर्तित किया जा सकता प्रकार का प्रसार "सूचक से सीवीvoid"।

वे (§3.9.2) बहुत अलग है कि मानक यहां तक ​​कि अपने रास्ते से बाहर चला जाता है यह सुनिश्चित करें कि शब्द "सूचक" गैर स्थिर सदस्यों की ओर इशारा शामिल नहीं है बनाने के लिए कर रहे हैं:

स्थिर सदस्यों को पॉइंटर्स को छोड़कर, "पॉइंटर्स" का जिक्र करते हुए टेक्स्ट सदस्यों को पॉइंटर्स पर लागू नहीं होता है।

+0

एकमात्र चीज़ जो आप 'शून्य * के साथ कर सकते हैं, उसे मूल पर वापस डालना है वैसे भी टाइप करें, इसलिए संभावित उपयोग का सवाल जरूरी नहीं है। आप '' '' के साथ 'शून्य *' को अस्वीकार नहीं कर सकते हैं। –

+0

@ जेम्ससांज ने इसे स्पष्ट करने के लिए इसे दोहराया। –

+0

सिवाय इसके कि यह अभी भी स्पष्ट नहीं है कि आपका मतलब "सामान्य पॉइंटर्स" से क्या है। ऑब्जेक्ट्स के लिए पॉइंटर्स (सी ++ समझ में) को 'शून्य *' में परिवर्तित किया जा सकता है। कार्यों के लिए सदस्यों और पॉइंटर्स के पॉइंटर्स नहीं कर सकते हैं। –

0

क्या आप ऐसा कुछ करने की कोशिश कर रहे हैं? कोई आवश्यकता है कि सदस्य के लिए एक सूचक डेटा के लिए सूचक रूप में एक ही आकार और प्रतिनिधित्व न होने के कारण

struct ABC 
{ 
    int a; 
    int b; 
    char c; 
}; 

int main() 
{ 
    ABC abc; 
    char *ptt1 = &abc.c; 
    void *another_ptr = (void*)ptt1; 
} 
+0

हाँ लेकिन बिना किसी ऑब्जेक्ट के – Paul

+0

किसी ऑब्जेक्ट के बिना यह अर्थहीन है, यद्यपि। – Damon

+1

यहां एक बहुत ही विस्तारित समानता है: आपने जो प्रयास किया वह घर के बजाय घर के ब्लूप्रिंट में एक नाखून पाउंड करने की कोशिश करना है। –

2

मुख्य कारण है। प्रैक्टिस में, को void* में फिट करने में सक्षम नहीं होने के कारण एक पॉइंटर को कल्पना करना मुश्किल है, क्योंकि डेटा सदस्य के लिए पॉइंटर वास्तव में केवल ऑफ़सेट होना आवश्यक है। असल में बोलते हुए, डेटा सदस्य के लिए एक सूचक size_t से बड़ा होने की आवश्यकता नहीं है, और void* कम से कम size_t जितना बड़ा होना चाहिए। दूसरी ओर, यह आसानी से बिट पैटर्न रख सकता है जो एक सूचक में कानूनी नहीं थे। वास्तव में, जैसे स्टीव जेसॉप बताते हैं, सदस्य को पॉइंटर्स को अतिरिक्त जानकारी की आवश्यकता होती है, क्योंकि यदि सदस्य वर्चुअल बेस में है, तो इसका ऑफसेट सबसे व्युत्पन्न वर्ग पर निर्भर करता है, और इसकी अतिरिक्त जानकारी के आधार पर गतिशील गणना की जानी चाहिए सूचक।

अधिक आम तौर पर, void* में डेटा में केवल पॉइंटर हो सकता है। यह सबसे बड़ा डेटा सूचक (आमतौर पर char*) के रूप में बड़ा होना चाहिए, लेकिन फ़ंक्शंस के लिए पॉइंटर्स और सदस्य पॉइंटर्स बड़े हो सकते हैं, और फिट नहीं हो सकते हैं (और सदस्य फ़ंक्शन के सूचक लगभग फिट नहीं होते हैं)।

+0

"डेटा सदस्य के सूचक को वास्तव में केवल ऑफसेट होना आवश्यक है" - जब तक कि सदस्य वर्चुअल बेस क्लास में न हो, उस स्थिति में जहां अधिक आवश्यकता हो (मुझे लगता है। क्या मैं गलत हूं, क्या यह केवल पॉइंटर-टू-सदस्य के साथ है -फंक्शन यह मुश्किल है?)। –

+0

@SteveJessop आप सही हैं। मुझे नहीं पता कि मैंने इसे एक साधारण ऑफसेट के रूप में प्रस्तुत किया था। वीसी 2012 के साथ, 32 बिट मोड, 'int *' का आकार 4 है, 'int कक्षा :: * '12. (इसके बारे में सोचने के लिए आओ, मुझे लगता है कि आखिरी बार मैंने वास्तव में इसे विस्तार से देखा था भाषा में एकाधिक विरासत जोड़ा गया था। और फिर, केवल कठिनाई आभासी कार्यों है।) –

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