2009-09-15 7 views
20

मैं इस की तर्ज पर एक समारोह लिखा है:फ़ंक्शन घोषणा में `* &` का क्या अर्थ है?

myStruct *data; 
myFunc(data); 

जो data में सभी क्षेत्रों को भरने जाएगा:

void myFunc(myStruct *&out) { 
    out = new myStruct; 
    out->field1 = 1; 
    out->field2 = 2; 
} 

अब एक कॉलिंग समारोह में, मैं कुछ इस तरह लिख सकते हैं। अगर मैं घोषणा में '&' छोड़ देता हूं, तो यह काम नहीं करेगा। (या बल्कि, यह केवल फ़ंक्शन में स्थानीय रूप से काम करेगा लेकिन कॉलर में कुछ भी नहीं बदलेगा)

क्या कोई मुझे बता सकता है कि यह '*&' वास्तव में क्या करता है? यह अजीब लग रहा है और मैं बस इसके बारे में ज्यादा समझ नहीं सकता।

+5

यह सी ++ वाक्यविन्यास है, सी – qrdl

उत्तर

34

& एक सी ++ परिवर्तनीय घोषणा में प्रतीक का अर्थ है कि यह reference है।

यह एक सूचक का संदर्भ होता है, जो आप देख रहे अर्थशास्त्र को बताते हैं; बुलाया गया फ़ंक्शन कॉलिंग संदर्भ में पॉइंटर बदल सकता है, क्योंकि इसका संदर्भ है।

तो, दोहराने के लिए, "ऑपरेटिव प्रतीक" यहां *& नहीं है, उस संयोजन में स्वयं का पूरा अर्थ नहीं है। *myStruct * प्रकार का हिस्सा है, यानी "myStruct पर पॉइंटर", और & इसे संदर्भ बनाता है, इसलिए आप इसे out के रूप में पढ़ेंगे क्योंकि myStruct पर पॉइंटर का संदर्भ है "।

मूल प्रोग्रामर मेरी राय में मदद की हो सकता है, के रूप में यह लिख कर:

void myFunc(myStruct * &out) 

या यहाँ तक कि (नहीं मेरे व्यक्तिगत शैली, लेकिन अभी भी निश्चित रूप से वैध):

void myFunc(myStruct* &out) 
के

पाठ्यक्रम, शैली के बारे में कई अन्य राय हैं। :)

+0

"... किसी अन्य की तरह और सी ++ में किसी नाम से पहले ..." थोड़ा सा मैला है। (जब ऐसा कहा जाता है, तो यह ऑपरेटर का पता भी हो सकता है।) फिर भी, अच्छा जवाब। +1 – sbi

+0

@ एसबीआई: सहमत, मैंने इसे बदल दिया ... अब यह शायद थोड़ा सा-रेफरेंसियल है। – unwind

+0

बेहतर अब, मुझे उम्मीद है। :) थोड़ा अकादमिक, क्योंकि Adriaan का जवाब स्वीकार कर लिया गया है। – unwind

2

C++ में यह एक सूचक के लिए एक संदर्भ, एक तरह से एक सूचक के बराबर सी सूचक को है, तो समारोह के तर्क को आबंटित है।

13

सी और सी ++ में, & का मतलब संदर्भ द्वारा कॉल करना है; आप फ़ंक्शन को चर बदलने की अनुमति देते हैं। इस मामले में आपका चर myStruct प्रकार के लिए एक सूचक है। इस मामले में फ़ंक्शन एक नई मेमोरी ब्लॉक आवंटित करता है और इसे आपके पॉइंटर 'डेटा' में निर्दिष्ट करता है।

अतीत में (कहें K & आर) यह एक सूचक को पास करके किया जाना था, इस मामले में एक पॉइंटर-टू-पॉइंटर या **। संदर्भ ऑपरेटर अधिक पठनीय कोड, और मजबूत प्रकार की जांच के लिए अनुमति देता है।

1

MyClass * & MyObject

यहाँ MyObject MyClass के एक सूचक के संदर्भ में है। तो मेरा फ़ंक्शन (MyClass * & MyObject) को संदर्भित करके कॉल किया जाता है, हम MyObject को बदल सकते हैं जो एक पॉइंटर का संदर्भ है। लेकिन अगर हम MyFunction (MyClass * MyObject) करते हैं तो हम MyObject को नहीं बदल सकते हैं क्योंकि यह मान द्वारा कॉल किया जाता है, यह केवल एक अस्थायी चर में पते की प्रतिलिपि बनायेगा ताकि हम उस मूल्य को बदल सकें जहां MyObject इंगित कर रहा है लेकिन MyObject नहीं है।

इसलिए इस मामले में लेखक पहले एक नया मूल्य निर्दिष्ट कर रहा है कि संदर्भ द्वारा कॉल क्यों जरूरी है।

6

ऐसा लगता है कि आप एक निर्माता को फिर से कार्यान्वित कर रहे हैं!

क्यों उचित कन्स्ट्रक्टर नहीं बनाते?
सी ++ में नोट एक संरचना एक वर्ग की तरह है (इसमें एक कन्स्ट्रक्टर हो सकता है)।

struct myStruct 
{ 
    myStruct() 
     :field1(1) 
     ,field2(2) 
    {} 
}; 

myStruct* data1 = new myStruct; 

// or Preferably use a smart pointer 
std::auto_ptr<myStruct> data2(new myStruct); 

// or a normal object 
myStruct data3; 
+0

वास्तव में, मैं एक निर्माता को फिर से कार्यान्वित कर रहा था। टिप के लिए धन्यवाद! – bastibe

2

सी ++ में अधिकांश डेटा प्रकारों के साथ, आप इसे दाएं से बाएं पढ़ सकते हैं और यह समझ में आ जाएगा।

myStruct *&out 

out एक myStruct वस्तु के लिए एक सूचक (*) के लिए एक संदर्भ (&) है। यह एक संदर्भ होना चाहिए क्योंकि आप out अंक (इस मामले में, new myStruct) को बदलना चाहते हैं।

6

यह समझाया जा सकता है कि यह &* क्यों नहीं है, लेकिन दूसरी तरफ। कारण है घोषणाओं रिकर्सिवली निर्माण कर रहे हैं, और इसलिए एक सूचक के लिए एक संदर्भ

& out // reference to ... 
* (& out) // reference to pointer 

कोष्ठकों क्योंकि वे अनावश्यक हैं छोड़ दिया जाता है की तरह बनाता है, लेकिन वे आप पैटर्न को देखने में मदद कर सकते हैं। (यह देखने के लिए कि वे अनावश्यक क्यों हैं, कल्पना करें कि चीज अभिव्यक्तियों में कैसा दिखती है, और आप देखेंगे कि पहला पता लिया गया है, और फिर संदर्भित किया गया है - यह वह आदेश है जिसे हम चाहते हैं और यह कि ब्रांड्स बदल नहीं पाएंगे)। यदि आप ऑर्डर बदलते हैं, तो आपको

* out // pointer to ... 
& (* out) // pointer to reference 

संदर्भ में सूचक कानूनी नहीं है। यही कारण है कि आदेश *& है, जिसका अर्थ है "सूचक का संदर्भ"।

3

अन्य लोगों की तरह, & का अर्थ है कि आप वास्तविक प्रतिरक्षा का संदर्भ ले रहे हैं क्योंकि इसकी प्रतिलिपि के विपरीत। इसका मतलब है कि फ़ंक्शन में चर के लिए किए गए कोई भी संशोधन मूल चर को प्रभावित करते हैं। जब आप एक पॉइंटर पास कर रहे होते हैं, तो यह विशेष रूप से भ्रमित हो सकता है, जो पहले से ही किसी और चीज का संदर्भ है। यदि आपके समारोह हस्ताक्षर इस

void myFunc(myStruct *out); 

की तरह दिखाई देता में क्या होगा कि आपके समारोह सूचक के साथ काम करने की एक प्रति पारित किया जाना होता है। इसका मतलब है कि सूचक एक ही बात पर इंगित करेगा, लेकिन एक अलग चर होगा। यहां, *out (यानी क्या बिंदुओं पर) पर किए गए कोई भी संशोधन स्थायी होंगे, लेकिन out (पॉइंटर स्वयं) में किए गए परिवर्तन केवल myFunc के अंदर लागू होंगे। इस

void myFunc(myStruct *&out); 

हस्ताक्षर के साथ आप यह घोषणा कर रहे हैं कि फ़ंक्शन मूल सूचक का संदर्भ लेगा। अब सूचक चर out में किए गए बदलाव मूल सूचक है कि में पारित किया गया था लाइन

out = new myStruct; 

को प्रभावित करेगा।

कहा जा रहा है, सूचक चर out और नहीं *out को संशोधित किया गया है।जो कुछ भी out इंगित करता है वह अभी भी जीवित और अच्छी तरह से है, लेकिन अब ढेर पर MyStruct का एक नया उदाहरण बनाया गया है, और out को इंगित करने के लिए संशोधित किया गया है।