2011-11-09 8 views
14

में निर्मित प्रकार can be value-initialized like this की चर:टाइप() - सिंटैक्स की तरह मैं टाइप * पॉइंटर को वैल्यू-स्टार्ट कैसे करूं?

int var = int(); 

इस तरह से मैं अपने कोड में शून्य हार्डकोड बिना int का डिफ़ॉल्ट मान मिलता है।

लेकिन अगर मैं एक सूचक के लिए इसी तरह के सामान करने की कोशिश:

int* ptr = int*(); 

संकलक (विजुअल C++ 10) संकलित करने के लिए है कि (type int unexpected कहते हैं) मना कर दिया।

मैं एक सूचक को समान तरीके से मूल्य-प्रारंभ कैसे करूं?

+1

अच्छा सवाल। आपको 'हस्ताक्षरित int' के लिए भी एक समान विफलता मिलती है। –

+1

अब सवाल यह है कि आप ऐसा क्यों करना चाहते हैं। आप सीधे 0 के साथ पॉइंटर्स प्रारंभ कर सकते हैं (यदि आपको पता है कि यह एक सूचक है), और यदि यह कुछ टेम्पलेट में छिपा हुआ है, तो 'टी()' ठीक काम करेगा ... मुझे नहीं पता कि यह प्रश्न 11 अपवॉट कैसे प्राप्त करता है:) –

उत्तर

4

मैं कैसे * सूचक प्रकार() का उपयोग मूल्य को प्रारंभ करते हैं एक प्रकार - वाक्य रचना की तरह?

आप नहीं कर सकते। वाक्यविन्यास T() को 5.2.3/1,2 (सी ++ 03, सी ++ 11 एफडीआईएस में थोड़ा अलग शब्द) में परिभाषित किया गया है।

अभिव्यक्ति टी(), जहां टी एक गैर सरणी पूरा ऑब्जेक्ट प्रकार या (संभवतः सीवी-योग्य) शून्य के लिए एक सरल प्रकार-विनिर्देशक (7.1.5.2) है: विशेष दूसरा पैराग्राफ राज्यों में टाइप करें, निर्दिष्ट प्रकार का एक रैल्यू बनाता है, जो मान-प्रारंभिक (8.5) है;

इसका मतलब है कि int(), प्रकार int और के एक rvalue पैदा करेगा यह मूल्य आरंभ कर। अब समस्या यह है कि int* एक साधारण प्रकार का विनिर्देशक नहीं है, बल्कि एक विस्तृत प्रकार-विनिर्देशक है। व्याकरण में सरल प्रकार-विनिर्देशक की परिभाषा है:

simple-type-specifier: 
    ::opt nested-name-specifieropt type-name 
    ::opt nested-name-specifier template template-id 
    char 
    wchar_t 
    bool 
    short 
    int 
    long 
    signed 
    unsigned 
    float 
    double 
    void 
साथ प्रकार- नाम

परिभाषित किया जा रहा है:

type-name: 
    class-name 
    enum-name 
    typedef-name 

इस प्रस्तावित समाधान काम करता है क्या है। टाइपपीफ (या तो सीधे या टेम्पलेट के माध्यम से) का निर्माण एक प्रकार का नाम (तीसरा प्रकार) बनाता है जिसे सरल-प्रकार-विनिर्देशक (प्रथम प्रकार) के रूप में उपयोग किया जा सकता है।

1

बस इसे शून्य पता दर्शाए क्योंकि आप इसे पूर्णांक का डिफ़ॉल्ट मान जो 0 वैसे भी है के साथ दोषी रहे हैं बनाने

int* x = int(); 

यह अभी भी प्रदान करती है सूचक को 0 से करते हैं।

वास्तव में, यह सभी प्रकार के लिए ठीक काम करता है:

double* y = int(); 

पता अब भी है एक 32-बिट (या 64-बिट मंच के आधार पर) पूर्णांक तो मुझे लगता है यह सभी प्रकार के लिए ठीक से काम करना चाहिए अगर आप do = int()।

template <typename T> 
T make_default() 
{ 
    return T(); 
} 

int main() 
{ 
    int *p = make_default<int*>(); 
} 
+0

वाह, प्रकार प्रणाली में एक प्रमुख उल्लंघन की तरह दिखता है और अविश्वसनीय रूप से अच्छा है। फिर भी यह 'डबल *' के लिए काम नहीं करेगा। – sharptooth

+0

हू, दिलचस्प :) मुझे इसे देखना होगा। मैंने सोचा होगा कि यह सभी सूचक प्रकारों के लिए काम करेगा। –

+0

मुझे लगता है कि यह ठीक काम करता है, मेरा संपादन देखें। –

1

यहाँ एक तरीका है

typedef int *ip; 

ip ptr = ip(); 

एक ही विचार अन्य प्रकार है कि एक से अधिक शाब्दिक तत्व की आवश्यकता के लिए काम करना चाहिए (शब्द) प्रकार के नाम को परिभाषित करने के लिए (उदाहरण के लिए, unsigned long, long long, unsigned long long *, आदि)।

+0

यह एक पूर्ण सूचक बनाने का एक तरीका है। – DanDan

9

अपने सूचक प्रकार के लिए एक नाम बनाने के लिए एक typedef का उपयोग करें::

+0

+1 - मेरा से आसान ... –

+0

मैं उलझन में हूं, एक सूचक केवल चर के स्मृति में पता रखता है - क्या यह केवल int * x = int() नहीं होना चाहिए, x पकड़ 0 बनाना जो न्यूल के समान है? मुझे लगता है कि मैं कुछ खो रहा हूं क्योंकि लोग पिछले मेरे पीछे छोड़ते रहते हैं, हाहा, मुझे हालांकि क्या नहीं मिलता है। –

+0

@ w00te: आपके समान प्रभाव होंगे, क्योंकि 0 को शून्य सूचक में कनवर्ट करने के लिए परिभाषित किया गया है। साथ ही, वह विशेष रूप से मूल्य प्रारंभ करने के तरीके के बारे में पूछ रहा है, और आप * ऐसा नहीं करते हैं ("वैल्यू प्रारंभिकरण" में सी ++ मानक में एक विशिष्ट परिभाषित अर्थ है जो सामान्य विचार से थोड़ा अलग है एक मूल्य के साथ शुरूआत)। –

-1

यह है कि आप इसे कैसे करते हैं int * ptr = new int;

Heap pointers

+2

यह सूचकांक को मूल्य-प्रारंभ नहीं करता है। –

0

कारण यह है कि काम नहीं करता है क्योंकि संकेत कंस्ट्रक्टर्स नहीं है।

वाक्य रचना

int()

कॉल (सिद्धांत में)

int::int()

जो चर initializes। (अधिक संभावना है, कंपाइलर सिर्फ चर शून्य है, लेकिन ऐसा इसलिए है क्योंकि यह इंट्स के बारे में "जानता है")।

C++ 11 में, आप nullptr

int *ptr = nullptr;

उपयोग कर सकते हैं अन्यथा, आप काफी शून्य का उपयोग करना होगा:

int *ptr = NULL;

+0

बेशक पॉइंटर्स के पास 'int' के समान तरीके से कन्स्ट्रक्टर होते हैं - यह सब कुछ अंतर्निहित है। मैं 'टी()' कह सकता हूं कि 'टी'' typedef int * टी' है, और मैं '= unsigned int()' का उपयोग नहीं कर सकता। यह समग्र रूप से पूरी तरह से वाक्य रचनात्मक समस्या है जो समग्र प्रकार के नामों के साथ काम नहीं कर रही है। – sbi

3

के उपयोग की आवश्यकता नहीं है typedef (लेकिन सी ++ 11 विशेष) है, जो उपयोगी है जब कई सूचक प्रकार के साथ काम कर हो सकता है:

template<typename T> 
using alias = T; 

तो alias<int*>int* है, तो आप int* p = alias<int*>() कर सकते हैं।

ऐसा ही एक समाधान सी ++ 03 के लिए उपलब्ध, एक पहचान metafunction का उपयोग कर:

template<typename T> 
struct identity { 
    typedef T type; 
}; 

int* p = identity<int*>::type(); 
+1

सी ++ 03 संस्करण को टाइपिफ़ की आवश्यकता होती है, यह सिर्फ टेम्पलेट के अंदर छिपी हुई है। सी ++ 11 संस्करण टाइपिफ़ नहीं बनाता है, लेकिन यह एक नया प्रकार 'उर्फ ' बनाता है जो * सरल-प्रकार-विनिर्देशक * बन जाता है और इस प्रकार * कार्यात्मक नोटेशन * –

+0

में * स्पष्ट प्रकार रूपांतरण * के लिए प्रवण होता है 'सूचक () 'नहीं है? ':)' – sbi

+0

@ एसबीआई 'उर्फ' के अन्य उपयोग हैं। –

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