कॉपी एलिजन एक कंपाइलर ऑप्टिमाइज़ेशन तकनीक है जो अनावश्यक कॉपीिंग / ऑब्जेक्ट्स को हिलाने से दूर करती है।
निम्नलिखित परिस्थितियों में, एक कंपाइलर को कॉपी / मूव ऑपरेशन को छोड़ने की अनुमति दी जाती है और इसलिए संबंधित कंस्ट्रक्टर को कॉल नहीं करना चाहिए:
- NRVO (नामांकित वापसी मूल्य अनुकूलन) : यदि कोई फ़ंक्शन मान के द्वारा एक वर्ग प्रकार देता है और रिटर्न स्टेटमेंट की अभिव्यक्ति स्वचालित भंडारण अवधि (जो फ़ंक्शन पैरामीटर नहीं है) के साथ एक गैर-वाष्पशील वस्तु का नाम है, तो प्रतिलिपि / चाल कि एक गैर-अनुकूलन संकलक द्वारा किया जाएगा छोड़ा जा सकता है। यदि ऐसा है, तो लौटाया गया मान सीधे उस स्टोरेज में निर्मित होता है जिसमें फ़ंक्शन का रिटर्न मान अन्यथा स्थानांतरित या कॉपी किया जाएगा।
- आरवीओ (रिटर्न वैल्यू ऑप्टिमाइजेशन) : यदि फ़ंक्शन नामहीन अस्थायी ऑब्जेक्ट लौटाता है जिसे एक भोली संकलक द्वारा स्थानांतरित या गंतव्य में कॉपी किया जाता है, तो प्रतिलिपि या चाल को 1 के अनुसार छोड़ा जा सकता है।
#include <iostream>
using namespace std;
class ABC
{
public:
const char *a;
ABC()
{ cout<<"Constructor"<<endl; }
ABC(const char *ptr)
{ cout<<"Constructor"<<endl; }
ABC(ABC &obj)
{ cout<<"copy constructor"<<endl;}
ABC(ABC&& obj)
{ cout<<"Move constructor"<<endl; }
~ABC()
{ cout<<"Destructor"<<endl; }
};
ABC fun123()
{ ABC obj; return obj; }
ABC xyz123()
{ return ABC(); }
int main()
{
ABC abc;
ABC obj1(fun123());//NRVO
ABC obj2(xyz123());//NRVO
ABC xyz = "Stack Overflow";//RVO
return 0;
}
**Output without -fno-elide-constructors**
root@ajay-PC:/home/ajay/c++# ./a.out
Constructor
Constructor
Constructor
Constructor
Destructor
Destructor
Destructor
Destructor
**Output with -fno-elide-constructors**
root@ajay-PC:/home/ajay/c++# g++ -std=c++11 copy_elision.cpp -fno-elide-constructors
root@ajay-PC:/home/ajay/c++# ./a.out
Constructor
Constructor
Move constructor
Destructor
Move constructor
Destructor
Constructor
Move constructor
Destructor
Move constructor
Destructor
Constructor
Move constructor
Destructor
Destructor
Destructor
Destructor
Destructor
यहां तक कि जब कॉपी एलिसन होता है और कॉपी- / मूव-कंस्ट्रक्टर को नहीं बुलाया जाता है, तो उसे मौजूद और एक्सेसिबल होना चाहिए (जैसे कि कोई ऑप्टिमाइज़ेशन बिल्कुल भी नहीं हुआ हो), अन्यथा प्रोग्राम बीमार हो जाता है।
आपको इस तरह के कॉपी इलिशन की अनुमति केवल उन्हीं जगहों पर देनी चाहिए, जहां यह आपके सॉफ्टवेयर के अवलोकन योग्य व्यवहार को प्रभावित नहीं करेगा। कॉपी एलिसेंस ऑप्टिमाइज़ेशन का एकमात्र रूप है (यानी एलीड) देखने योग्य साइड-इफेक्ट्स। उदाहरण:
#include <iostream>
int n = 0;
class ABC
{ public:
ABC(int) {}
ABC(const ABC& a) { ++n; } // the copy constructor has a visible side effect
}; // it modifies an object with static storage duration
int main()
{
ABC c1(21); // direct-initialization, calls C::C(42)
ABC c2 = ABC(21); // copy-initialization, calls C::C( C(42) )
std::cout << n << std::endl; // prints 0 if the copy was elided, 1 otherwise
return 0;
}
Output without -fno-elide-constructors
root@ajay-PC:/home/ayadav# g++ -std=c++11 copy_elision.cpp
root@ajay-PC:/home/ayadav# ./a.out
0
Output with -fno-elide-constructors
root@ajay-PC:/home/ayadav# g++ -std=c++11 copy_elision.cpp -fno-elide-constructors
root@ajay-PC:/home/ayadav# ./a.out
1
जीसीसी प्रदान करता है -fno-elide-constructors
कॉपी एलीशन को निष्क्रिय करने विकल्प । यदि आप संभावित नकल से बचना चाहते हैं, तो उपयोग करें -fno-elide-constructors
।
अब लगभग सभी कंपाइलर ऑप्टिमाइज़ेशन सक्षम होने पर कॉपी एलीगेशन प्रदान करते हैं (और यदि कोई अन्य विकल्प इसे अक्षम करने के लिए सेट नहीं है)।
निष्कर्ष
प्रत्येक कॉपी एलीज़न के साथ, एक निर्माण और कॉपी के एक मिलान विनाश को छोड़ दिया जाता है, इस प्रकार सीपीयू समय की बचत होती है, और एक ऑब्जेक्ट नहीं बनता है, इस प्रकार स्टैक फ्रेम पर जगह की बचत होती है।