मैं कुछ कोड में आया हूं जो मुझे डराता है। मूलतः यह इस पद्धति का अनुसरण करता:सी ++ प्लेसमेंट नए अपरिभाषित व्यवहार का उपयोग कर ऑब्जेक्ट का निर्माण दो बार कर रहा है?
class Foo
{
public:
//default constructor
Foo(): x(0), ptr(nullptr)
{
//do nothing
}
//more interesting constructor
Foo(FooInitialiser& init): x(0), ptr(nullptr)
{
x = init.getX();
ptr = new int;
}
~Foo()
{
delete ptr;
}
private:
int x;
int* ptr;
};
void someFunction(FooInitialiser initialiser)
{
int numFoos = MAGIC_NUMBER;
Foo* fooArray = new Foo[numFoos]; //allocate an array of default constructed Foo's
for(int i = 0; i < numFoos; ++i)
{
new(fooArray+ i) Foo(initialiser); //use placement new to initialise
}
//... do stuff
delete[] fooArray;
}
इस कोड को साल के लिए कोड बेस में किया गया है और यह प्रतीत होता है एक समस्या कभी नहीं हुई है। यह स्पष्ट रूप से एक बुरा विचार है क्योंकि कोई दूसरा निर्माण करने की अपेक्षा न करने के लिए डिफ़ॉल्ट कन्स्ट्रक्टर बदल सकता है। बस समकक्ष प्रारंभिक विधि के साथ दूसरे कन्स्ट्रक्टर को प्रतिस्थापित करने के लिए समझदार चीज़ लगती है। जैसे।
void Foo::initialise(FooInitialiser& init)
{
x = init.getX();
ptr = new int;
}
हालांकि अभी भी संभव संसाधन लीक करने के लिए विषय, कम से कम एक रक्षात्मक प्रोग्रामर एक सामान्य विधि में पूर्व आवंटन की जांच करने के बारे में सोच सकता है।
मेरा प्रश्न है:
दो बार निर्माण कर रही है यह वास्तव में अपरिभाषित व्यवहार की तरह/मानक या बस सिर्फ एक बुरा विचार द्वारा गैरकानूनी घोषित? यदि अपरिभाषित व्यवहार आप मानक को देखने के लिए सही स्थान पर उद्धृत या इंगित कर सकते हैं?
क्या आपने इस कोड पर valgrind करने की कोशिश की? – zoska
मुझे लगता है कि मुख्य समस्या यह है कि 'Foo' तीन के नियम का पालन नहीं करता है - डिफ़ॉल्ट प्रति-ctor और कॉपी-असाइनमेंट-ऑपरेटर' Foo :: ptr' के साथ सही चीज़ नहीं करेगा। – cdhowie
@cdhowie शायद हमें अन्य लोगों के कोड के बारे में सबसे बुरा नहीं मानना चाहिए। मुझे लगता है कि ओपी ने उस कोड को काट दिया जो सवाल पूछने के लिए जरूरी नहीं था। – anatolyg