2013-05-24 7 views
5

पर मान द्वारा तर्क के रूप में ऑब्जेक्ट पास करते हैं तो मैं प्रतिलिपि बनाता हूं, जब मैं कुछ सी ++ प्रोग्राम कर रहा हूं, तो मुझे संदेह है कि यही कारण है कि जब मैं पास करता हूं तो कॉपी कन्स्ट्रक्टर को कॉल किया जाता है किसी ऑब्जेक्ट को फ़ंक्शन के मान के आधार पर तर्क के रूप में। कृपया मेरा नीचे कोड देखें कि मैं वर्ग के ऑब्जेक्ट को फ़ंक्शन डिस्प्ले() पर मान के आधार पर तर्क के रूप में पास कर रहा हूं लेकिन यह कॉपी कन्स्ट्रक्टर को कॉल कर रहा है और फिर नियंत्रण डिस्प्ले() फ़ंक्शन को मार रहा है लेकिन मुझे समझ में आता है कि यह क्यों मदद करता है।जब हम ऑब्जेक्ट को किसी विधि

#include "stdafx.h" 
#include <iostream> 
using namespace std; 

class ClassA 
{ 
    private: 
     int a, b; 
    public: 
     ClassA() 
     { 
      a = 10, b = 20; 
     } 
     ClassA(ClassA &obj) 
     { 
      cout << "copy constructor called" << endl; 
      a = obj.a; 
      b = obj.b; 
     } 
}; 
void display(ClassA obj) 
{ 
    cout << "Hello World" << endl; 
} 
int main() 
{ 
    ClassA obj; 
    display(obj); 
    return 0; 
} 

उत्तर

6

दो जवाब थोड़ा विस्तार से बता दें पहले ही दिया:

जब आप कुछ अन्य चर "के रूप में ही" हो वैरिएबल निर्धारित है, तो आप मूल रूप से दो संभावनाएं हैं: इसके बजाय

ClassA aCopy = someOtherA; //copy 
ClassA& aRef = someOtherA; //reference 

गैर की कॉन्स लैवल्यू संदर्भ निश्चित रूप से कॉन्स संदर्भ और रावल संदर्भ हैं। मुख्य बात यह है कि मैं यहां इंगित करना चाहता हूं कि aCopysomeOtherA से स्वतंत्र है, जबकि aRef व्यावहारिक रूप से someOtherA के समान चर है, यह इसके लिए एक और नाम (उपनाम) है।

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

void f(int& iRef) { 
    ++iRef; 
} 

int main() { 
    int i = 5; 
    f(i); //i becomes 6, because iRef IS i 
} 

जब पैरामीटर एक मूल्य है, यह केवल तर्क की एक प्रति है, इसलिए परवाह किए बिना क्या आप पैरामीटर के लिए करते हैं, तर्क कुछ नहीं बदला है।

void f(int iCopy) { 
    ++iCopy; 
} 

int main() { 
    int i = 5; 
    f(i); //i remains 5, because iCopy IS NOT i 
} 

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

स्थिरांक & द्वारा रीड-ओनली पैरामीटर गुजर अगर आप केवल यह से पढ़ने के लिए जा रहे हैं पसंद करते हैं:

GotW #4 से एक दिशानिर्देश नहीं है।

4

एक समारोह के लिए मूल्य से गुजर मतलब है क्योंकि समारोह वस्तु की अपनी स्वयं की प्रतिलिपि है। इस अंत में, कॉपी कन्स्ट्रक्टर कहा जाता है।

void display(ClassA obj) 
{ 
    // display has its own ClassA object, a copy of the input 
    cout << "Hello World" << endl; 
} 

ध्यान रखें कि कुछ मामलों में प्रतियों को बढ़ाया जा सकता है, उदाहरण के लिए, यदि कार्य में अस्थायी मूल्य पारित किया जाता है।

2

जैसा कि जुंचोपांजा ने कहा था :, आप मूल्य से गुजरते हैं, जिससे एक प्रतिलिपि बनती है। आप इसे रोकने के लिए चाहते हैं तो आप संदर्भ द्वारा पारित कर सकते हैं:

void display(const ClassA &obj) 

एक sidenote पर:

ClassA(const ClassA &obj) 

नहीं तो आप नहीं होगा: आप स्थिरांक संदर्भ के रूप में तर्क लेने के लिए आपके प्रति ctor घोषित करना चाहिए नामित वस्तुओं पर प्रतिलिपि या अस्थायी के रूप में चिह्नित प्रतिलिपि ctor का उपयोग करने में सक्षम। यह आपको गुजरने वाली वस्तु को गलती से बदलने से भी रोकता है।

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