2015-02-21 14 views
6

हम दो तरीकों से एक वस्तु बना सकते हैं:क्या इन दो लाइनों के बीच कोई अंतर है?

myClass myObject = myClass(123); 
//or 
myClass myObject(123); 

वहाँ इन दोनों के बीच पृष्ठभूमि में कोई अंतर है? मैं पहले का उपयोग करना चाहता हूं लेकिन ऐसा लगता है कि इन दो लाइनों को जोड़ना:

myClass myObject; 
myObject= myClass(123); 

क्या दूसरा भी वही काम करता है?

+3

एक बार संकलित कोई अंतर नहीं। –

उत्तर

10
myClass myVariable = myClass(123); 

copy initialization है।

myClass myVariable(123); 

direct initialization है।

myClass myVariable; 
myVariable = myClass(123); 

default initializationcopy (or move) assignment द्वारा पीछा किया।

आमतौर पर, पहले दो copy elision की वजह से समान हैं। प्रासंगिक नियम [class.copy] में पाया जा सकता/31 (N4140, सी ++ 14 मसौदा मानक):

जब कुछ मानदंडों को पूरा किया जाता है, एक कार्यान्वयन की कॉपी/कदम निर्माण न करने का अनुमति दी है एक वर्ग वस्तु [...]:

- जब एक अस्थायी वर्ग वस्तु है कि एक संदर्भ (12 करने के लिए बाध्य नहीं किया गया।2) कॉपी किया जाएगा/एक ही सीवी-अयोग्य प्रकार के साथ एक वर्ग वस्तु में ले जाया गया, कॉपी/कदम आपरेशन अस्थायी वस्तु छोड़े गए प्रतिलिपि का लक्ष्य में सीधे निर्माण करके छोड़ा जा सकता है/ले जाने के

+0

धन्यवाद। मैं प्रत्यक्ष प्रारंभिक उपयोग का उपयोग करने के लिए बेहतर उपयोग करता हूं क्योंकि संदर्भ कहता है कि: _Copy- प्रारंभिकरण प्रारंभिक प्रारंभिक से कम अनुमोदित है: प्रति-प्रारंभिकरण केवल गैर-स्पष्ट रचनाकारों और उपयोगकर्ता परिभाषित रूपांतरण कार्यों को मानता है ._ – farukdgn

+0

धन्यवाद! और तस्वीर को पूरा करने के लिए, [class.expl.init]/1 हमें बताता है कि * "वर्ग प्रकार का एक ऑब्जेक्ट को एक संश्लेषित अभिव्यक्ति-सूची के साथ प्रारंभ किया जा सकता है, जहां अभिव्यक्ति-सूची किसी निर्माता के लिए तर्क सूची के रूप में समझा जाता है जिसे ऑब्जेक्ट को प्रारंभ करने के लिए बुलाया जाता है। वैकल्पिक रूप से, एक असाइनमेंट-एक्सप्रेशन प्रारंभिकरण के '=' रूप का उपयोग करके प्रारंभकर्ता के रूप में निर्दिष्ट किया जा सकता है। ** या तो प्रत्यक्ष-प्रारंभिक अर्थशास्त्र या प्रति-प्रारंभिक अर्थशास्त्र लागू होते हैं *** – Christophe

+1

पहला यदि कक्षा प्रतिलिपि का समर्थन नहीं करती है तो दो समान हैं, इस मामले में, पहला संकलन नहीं करेगा। –

1

मैं के बारे में पता है कि नहीं, अंत में। आपने ऑब्जेक्ट को परिभाषित करने के तीन तरीकों का वर्णन किया है और सभी 3 तरीके ऑब्जेक्ट को स्टैक के शीर्ष पर रखते हैं, उसी कन्स्ट्रक्टर को कॉल करते हैं। यदि आपने new ऑपरेटर का उपयोग किया तो कार्यक्षमता अलग होगी।

+1

वे सभी समकक्ष नहीं हैं, और 'नया' ऑपरेटर यहां अप्रासंगिक है, यह नहीं बदलेगा कि कौन से निर्माता या विशेष सदस्य कार्य कहलाते हैं। – 0x499602D2

+0

दो पहले बराबर हैं तीसरे एक अलग हैं। – Christophe

+1

@ क्रिस्टोफ़े पहले दो बराबर नहीं हैं यदि 'myClass' की एक स्पष्ट प्रति/चाल-निर्माता है। – 0x499602D2

1

यह एक असाइनमेंट ऑपरेटर (के रूप में मैं जानता हूँ कि दो लाइनों, बराबर हैं जहाँ तक) का उपयोग नहीं करता। = वाक्य रचना में प्रयोग किया जाता है लेकिन वास्तव में operator= नहीं किया जाता है: असाइनमेंट ऑपरेटर बुरी तरह से है या नहीं लागू किया गया है

myClass myVariable; 
myVariable = myClass(123); 

हैं, तो पहले बयान काम करता है, दूसरा हो सकता है (:

myClass myVariable = myClass(123); 
//or 
myClass myVariable(123); 

यह एक असाइनमेंट ऑपरेटर का उपयोग करता है और सबसे अधिक संभावना है) दुर्घटना।

#include <iostream> 
#include <string.h> 
using namespace std; 

class Dvector 
{ 
public: 
    Dvector(int thesize = 0) 
    { 
     std::cout << "Constructing object of size " << thesize << std::endl; 
     size = thesize; 
     data = new double[size]; 
    } 
    Dvector(const Dvector& v) 
    { 
     std::cout << "Constructing object of size " << v.size << " by copy" << std::endl; 
     size = v.size; 
     data = new double[size]; 
     memcpy(data, v.data, sizeof(double)*size); 
    } 
    Dvector& operator=(const Dvector& v) 
    { 
     std::cout << "Assigning object of size " << v.size << std::endl; 
     if (&v != this) 
     { 
      size = v.size; 
      data = new double[size]; 
      memcpy(data, v.data, sizeof(double)*size); 
     } 
     return *this; 
    } 
    ~Dvector() 
    { 
     std::cout << "Destroying object" << std::endl; 
     delete [] data; 
    } 
private: 
    double* data; 
    int size; 
}; 

int main() { 
    Dvector v = Dvector(3); 
    return 0; 
} 

प्रदर्शित करता है:

Constructing object of size 3 
Destroying object 

जब:

int main() { 
    Dvector v; 
    v = Dvector(3); 
    return 0; 
} 

प्रदर्शित करता है:

Constructing object of size 0 
Constructing object of size 3 
Assigning object of size 3 
Destroying object 
Destroying object 

और अगर प्रतिलिपि निर्माता परिभाषित नहीं किया गया था दुर्घटनाग्रस्त हो गया है | ... क्योंकि तब v.data इंगित करने के लिए समाप्त होता है अस्थायी चर (Dvector(3)) द्वारा आवंटित data और फिर हटा दिया गया। संभावित दुर्घटना जब v.data या पर v विनाश (पहले से ही मुक्त कर दिया स्मृति को हटाने) का उपयोग करने की कोशिश कर रहा।

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