2009-11-27 21 views
10

और यदि हां, तो कुछ Win32 शीर्षलेख इसका उपयोग क्यों करते हैं?"शून्य * कॉन्स्ट" के बराबर "कॉन्स्ट एलपीवीओआईडी" है?

उदाहरण के लिए:

BOOL APIENTRY VerQueryValueA(const LPVOID pBlock, 
    LPSTR lpSubBlock, 
    LPVOID * lplpBuffer, 
    PUINT puLen 
    ); 

एक थोड़ा और अधिक विस्तार: एपीआई (या किसी अन्य सी ++ - केवल निर्माण करती है) के संदर्भ में कभी नहीं का उपयोग करता है, लेकिन केवल संकेत और मूल्यों, const LPVOID बनाम LPCVOID होने की बात क्या है ।

क्या मुझे ऐसी जगह चाहिए जहां मैं को किसी स्थान के रूप में देख सकता हूं जहां वास्तविक अर्थ LPCVOID है? (और इस प्रकार यह एक कास्ट जोड़ने के लिए सुरक्षित है)

और स्पष्टीकरण: ऐसा प्रतीत होता है कि const LPVOID pBlock वास्तव में इस मामले में एक गलती थी। विंडोज 2008 एसडीके हस्ताक्षर में इसे LPCVOID पर बदल देता है। कुछ समय पहले शराब ने ऐसा किया था।

+1

मैंने सुना है कि वे उन चीजों को परिभाषित करते हैं, इसलिए यह 'कॉन्स्ट शून्य *' होगा। यदि वे टाइपपीफ हैं, तो यह वास्तव में 'शून्य * const' होगा। –

+0

@litb: दुर्भाग्य से ये टाइप किए गए हैं – EFraim

+0

@EFraim, आह मैं देखता हूं। शापित ऊपरी मामला :) –

उत्तर

12

एक typedef नाम एक प्रकार को दर्शाता है, और नहीं टोकन के एक अनुक्रम (के रूप में एक मैक्रो करता है)। आपके मामले में, LPVOID टोकन अनुक्रम void * द्वारा निर्दिष्ट प्रकार को भी दर्शाता है। तो चित्र की तरह

// [...] is the type entity, which we cannot express directly. 
LPVOID => [void *] 

शब्दार्थ लग रहा है अगर तुम प्रकार const LPVOID निर्दिष्ट करते हैं, आप निम्न आरेख मिल (विनिर्देशक के आसपास कोष्ठक मतलब है "प्रकार निर्दिष्टकर्ता से दर्शाया जाता है"):

// equivalent (think of "const [int]" and "[int] const"): 
const LPVOID <=> LPVOID const => const [void *] <=> [void *] const 
           => ["const qualified void-pointer"] 

यह टोकन अनुक्रम const void * जैसा ही नहीं है - क्योंकि यह एक कॉन्स्टेबल पॉइंटर प्रकार को इंगित नहीं करेगा, बल्कि एक कॉन्स योग्य प्रकार के लिए एक सूचक है (जिस चीज को इंगित किया जाएगा)।

वाक्य रचना एक पैरामीटर घोषणा के बाद (सरलीकृत) रूप है: const void *p के मामले में

declaration-specifiers declarator 

घोषणा-विनिर्देशक const void हैं - तो *p के आधार प्रकार एक स्थिरांक योग्य है void, लेकिन सूचक स्वयं योग्य नहीं है। const LPVOID p के मामले में हालांकि घोषणा-विनिर्देशक एक कॉन्स योग्य LPVOID निर्दिष्ट करते हैं - जिसका अर्थ है कि पॉइंटर प्रकार स्वयं योग्य है, पैरामीटर घोषणा void *const p के समान है।

+1

रुको, अब मैं उलझन में हूं। कॉन्स शून्य * और शून्य * कॉन्स समान नहीं हैं। – EFraim

+1

@EFraim, 'शून्य *' के आस-पास के बॉक्स का अर्थ है कि यह 'एलपीवीओआईडी' द्वारा निर्दिष्ट प्रकार है - इसका मतलब यह नहीं है कि पाठ घोषणा में प्रकट होता है। –

+0

आह, ठीक है, इस आरेख ने मुझे उलझन में डाल दिया। – EFraim

0

एलपीवीओआईडी बहुत सामान्य सूचक है, जो सामान्य जेनेरिक सूचक के रूप में पहले से ही लंबा है (यह पुराने 16 बिट प्लेटफॉर्म पर अलग था)।

+1

जो ठीक है, हालांकि सवाल के विषय में बहुत कम करना है। – EFraim

0
void* const x = 0; 
x = 0; // this line will not compile - u cannot change x, only what it points to 
x->NonConstMethod(); // will compile 
const void* y = 0; 
y = 0; // this line will compile - u can change y, but not what it points to 
y->NonConstMethod(); // will not compile 
const void* const z = 0; // u cannot change z or what it points to 
// btw, the type of the 'this' pointer is "ClassName* const this;" 
संबंधित मुद्दे