दिलचस्प पोस्ट
आईडी में अवधि के साथ सीएसएस चयनकर्ता क्या जावास्क्रिप्ट के माध्यम से एक लिंक (या किसी तत्व का) क्लिक करें ईवेंट को ट्रिगर करना संभव है? एचटीएमएल-स्ट्रिंग से jQuery को टैग हटाने लैम्ब्डा अभिव्यक्ति में विदेशी लैप के इटरेटर वेरिएबल का उपयोग करना – क्यों विफल रहता है? एएसपी.नेट एमवीसी 5 में फेसबुक v2.4 एपीआई से OAuth ExternalLogin कॉलबैक में ईमेल पते पर पहुंचें जावास्क्रिप्ट; समान मूल के साथ टैब / विंडो के बीच संचार मैक्सलेम्बन एट्रिब्यूट ग्राहक-साइड सत्यापन विशेषताएँ पैदा नहीं कर रहा है HTTP से यूनिसेप पायथन स्ट्रिंग्स उच्च रिज़ॉल्यूशन इमेज – आउटऑफममेरीएरर कैसे बराबर के लिए जाँच करने के लिए? (0 == i) या (i == 0) Runtime.getRuntime ()। कार्यकारी () पृष्ठ रिफ्रेश होने पर फ़ॉर्म रीब्यूमिशन कैसे रोकें (F5 / CTRL + R) JQuery में, एक div के सभी HTML को हटाना चाहते हैं सुडो परिवर्तन पाथ – क्यों? मैं खिड़कियों पर स्रोत टर्बल से एक आर पैकेज कैसे स्थापित करूं?

डिफ़ॉल्ट निर्माता के बिना ऑब्जेक्ट सरणी प्रारंभ

#include <iostream> class Car { private: Car(){}; int _no; public: Car(int no) { _no=no; } void printNo() { std::cout<<_no<<std::endl; } }; void printCarNumbers(Car *cars, int length) { for(int i = 0; i<length;i++) std::cout<<cars[i].printNo(); } int main() { int userInput = 10; Car *mycars = new Car[userInput]; for(int i =0;i < userInput;i++) mycars[i]=new Car[i+1]; printCarNumbers(mycars,userInput); return 0; } 

मैं एक कार सरणी बनाना चाहता हूं लेकिन मुझे निम्न त्रुटि मिलती है:

 cartest.cpp: In function 'int main()': cartest.cpp:5: error: 'Car::Car()' is private cartest.cpp:21: error: within this context 

क्या कार () कंस्ट्रक्टर सार्वजनिक किए बिना इस आरंभीकरण को बनाने का कोई तरीका है?

Solutions Collecting From Web of "डिफ़ॉल्ट निर्माता के बिना ऑब्जेक्ट सरणी प्रारंभ"

नहीं।

लेकिन लो! यदि आप std::vector<Car> का उपयोग करते हैं, जैसे आप (कभी भी new[] का उपयोग नहीं करते हैं), तो आप बिल्कुल निर्दिष्ट कर सकते हैं कि कैसे तत्वों का निर्माण किया जाना चाहिए *।

*अच्छी तरह की। आप उस मूल्य को निर्दिष्ट कर सकते हैं जिसके प्रति की प्रतिलिपि बनाने के लिए।


इस कदर:

 #include <iostream> #include <vector> class Car { private: Car(); // if you don't use it, you can just declare it to make it private int _no; public: Car(int no) : _no(no) { // use an initialization list to initialize members, // not the constructor body to assign them } void printNo() { // use whitespace, itmakesthingseasiertoread std::cout << _no << std::endl; } }; int main() { int userInput = 10; // first method: userInput copies of Car(5) std::vector<Car> mycars(userInput, Car(5)); // second method: std::vector<Car> mycars; // empty mycars.reserve(userInput); // optional: reserve the memory upfront for (int i = 0; i < userInput; ++i) mycars.push_back(Car(i)); // ith element is a copy of this // return 0 is implicit on main's with no return statement, // useful for snippets and short code samples } 

अतिरिक्त कार्य के साथ:

 void printCarNumbers(Car *cars, int length) { for(int i = 0; i < length; i++) // whitespace! :) std::cout << cars[i].printNo(); } int main() { // ... printCarNumbers(&mycars[0], mycars.size()); } 

ध्यान दें कि printCarNumbers वास्तव में अलग तरीके से डिज़ाइन किया जाना चाहिए, एक रेंज को दर्शाती दो printCarNumbers को स्वीकार करने के लिए।

आप इस तरह प्लेसमेंट-नया उपयोग कर सकते हैं:

 class Car { int _no; public: Car( int no ) :_no( no ) { } }; int main() { void* raw_memory = operator new[]( NUM_CARS * sizeof( Car ) ); Car* ptr = static_cast<Car*>( raw_memory ); for( int i = 0; i < NUM_CARS; ++i ) { new( &ptr[i] )Car( i ); } // destruct in inverse order for( int i = NUM_CARS - 1; i >= 0; --i ) { ptr[i].~Car(); } operator delete[]( raw_memory ); return 0; } 

अधिक प्रभावी सी + + – स्कॉट मेयेर से संदर्भ:
मद 4 – अनावश्यक डिफ़ॉल्ट कन्स्ट्रक्टर से बचें

आप पॉइंटर्स की सरणी बना सकते हैं

 Car** mycars = new Car*[userInput]; for (int i=0; i<userInput; i++){ mycars[i] = new Car(...); } ... for (int i=0; i<userInput; i++){ delete mycars[i]; } delete [] mycars; 

या

कार () निर्माता को सार्वजनिक होने की आवश्यकता नहीं है अपनी कक्षा में एक स्थिर विधि जोड़ें जो एक सरणी बनाता है:

 static Car* makeArray(int length){ return new Car[length]; } 

नहीं, नहीं है। नया-अभिव्यक्ति केवल डिफ़ॉल्ट प्रारंभिकता या सभी पर कोई आरंभीकरण की अनुमति नहीं देता है।

वैकल्पिक हल operator new[] का प्रयोग करके कच्चे मेमोरी बफर आवंटित करना होगा operator new[] और उसके बाद उस बफर में ऑब्जेक्ट का निर्माण करेगी जो कि गैर-डिफॉल्ट कन्स्ट्रक्टर के साथ नियुक्ति-नया का उपयोग करे।

अच्छा प्रश्न। मेरे पास एक ही प्रश्न था, और इसे यहां मिला। असली जवाब है, @ दान-पैराडोक्स, ऐसा करने का कोई मानक वाक्यविन्यास तरीका नहीं है। इसलिए, ये सभी उत्तर समस्या के आसपास आने के लिए कई विकल्प हैं।

मैंने खुद को जवाब पढ़ा, और विशेष रूप से मेरे निजी सम्मेलन के लिए उनमें से किसी को भी सही नहीं मिला। जिस पद्धति से मैं शायद छड़ी करूँगा वह एक डिफ़ॉल्ट कन्स्ट्रक्टर और एक set विधि का उपयोग कर रहा है:

 क्लास मायक्लास
 {
   int x, y, z;
 जनता:
   MyClass (): x (0), y (0), z (0) {}
   MyClass (int _x, int _y, int _z): एक्स (_ x), y (_y), z (_z) {} // एकल घोषणाओं के लिए
   शून्य सेट (int _x, int_y, int _z)
   {
     एक्स = _x;
     y = _y;
     z = _z;
   }
 };

मानक इनिशियलाइज़ेशन कन्स्ट्रक्टर अभी भी वहां है, इसलिए मैं अभी भी इसे सामान्य रूप से प्रारंभ कर सकता हूं अगर मुझे एक से अधिक की आवश्यकता न हो, लेकिन यदि अन्यथा, मेरे पास एक set विधि है जो कन्स्ट्रक्टर में शुरू किए गए सभी चर सेट करता है। इस प्रकार मैं ऐसा कुछ कर सकता हूं:

 इंट लेन = 25;
 मायक्लैस सूची = नया मायक्लास [लेन];
 के लिए (इंट i = 0; i <len; i ++)
   सूची [i] .Set (1,2,3);

यह ठीक काम करता है और स्वाभाविक रूप से प्रवाह करता है, बिना कोड को भ्रमित करने वाला लग रहा है


अब यह उन लोगों के लिए मेरा जवाब है, जो सोचते हैं कि किस प्रकार ऑब्जेक्ट्स की एक सरणी को आरम्भ करने की जरूरत है

आपके लिए विशेष रूप से, आप कारों की पहचान की एक सरणी देने की कोशिश कर रहे हैं, जो मुझे लगता था कि आप हमेशा अद्वितीय होना चाहते हैं आप इसे मेरी विधि से ऊपर बताए गए विधि के साथ कर सकते हैं, और फिर लूप के लिए i+1 को set विधि में भेजे गए तर्क के रूप में उपयोग करें – लेकिन मैंने आपकी टिप्पणियों में जो पढ़ा है, ऐसा लगता है जैसे आप आईडी अधिक आंतरिक रूप से चाहते हैं आरंभ किया गया, ताकि डिफ़ॉल्ट रूप से प्रत्येक कार का एक अनूठा आईडी हो, भले ही कोई अन्य आपकी क्लास Car का उपयोग करे।

यदि यह वही है जो आप चाहते हैं, तो आप एक स्थिर सदस्य का उपयोग कर सकते हैं:

 कक्षा कार
 {
   स्थैतिक इंट वर्तमान_आईडी;
   int आईडी;
 जनता:
   कार (): आईडी (चालू_आईडी ++) {}

   int getId () {वापसी आईडी;  }
 };
 इंट कार :: current_id = 1;

 ...

 इंट कारें = 10;
 कार * कारलिस्ट = नई कार [कार];

 के लिए (इंट I = 0; i <कार; आई ++)
   cout << कारलिस्ट [i] .getId () << "";  // प्रिंट "1 2 3 4 5 6 7 8 9 10"

इस तरह, आपको आइडेंटिटी शुरू करने के बारे में चिंता करने की ज़रूरत नहीं है क्योंकि इन्हें आंतरिक रूप से प्रबंधित किया जाता है।

आप हमेशा पॉइंट्स की एक सरणी बना सकते हैं, कार ऑब्जेक्ट की ओर इशारा करते हैं और फिर ऑब्जेक्ट्स बना सकते हैं, लूप में, जैसा आप चाहते हैं और सरणी में उनका पता सहेज सकते हैं, उदाहरण के लिए:

 #include <iostream> class Car { private: Car(){}; int _no; public: Car(int no) { _no=no; } void printNo() { std::cout<<_no<<std::endl; } }; void printCarNumbers(Car *cars, int length) { for(int i = 0; i<length;i++) std::cout<<cars[i].printNo(); } int main() { int userInput = 10; Car **mycars = new Car*[userInput]; int i; for(i=0;i<userInput;i++) mycars[i] = new Car(i+1); 

नई पद्धति नोट करें !!!

  printCarNumbers_new(mycars,userInput); return 0; } 

आपको नई पद्धति में बदलाव करना होगा, पैरामीटर के रूप में कारकों को स्टैंटिक ऑब्जेक्ट्स की तुलना में कारों के रूप में संभालना होगा और उदाहरण के लिए printNo () विधि को कॉल करते समय:

 void printCarNumbers_new(Car **cars, int length) { for(int i = 0; i<length;i++) std::cout<<cars[i]->printNo(); } 

मुख्य के अंत में इस तरह से सभी गतिशील आवंटित मेमोरी को हटाने के लिए अच्छा है

 for(i=0;i<userInput;i++) delete mycars[i]; //deleting one obgject delete[] mycars; //deleting array of objects 

आशा है कि मैंने मदद की, चियर्स!

सी ++ 11 के emplace_back std::vector आप emplace_back का प्रयोग करके तत्वों को इन्स्तांत कर सकते हैं:

  std::vector<Car> mycars; for (int i = 0; i < userInput; ++i) { mycars.emplace_back(i + 1); // pass in Car() constructor arguments } 

देखा!

कार () डिफ़ॉल्ट कन्स्ट्रक्टर का कभी भी उपयोग नहीं किया गया

mycars के दायरे से बाहर निकल जाने पर विलोपन स्वतः हो जाएगा।

हल करने का एक तरीका सरणी आवंटित करने के लिए एक स्थिर कारखाना विधि देना है, अगर किसी कारण से आप कन्स्ट्रक्टर निजी देना चाहते हैं

 static Car* Car::CreateCarArray(int dimensions) 

लेकिन आप एक कन्स्ट्रक्टर सार्वजनिक और अन्य निजी क्यों रख रहे हैं?

लेकिन किसी भी तरह से एक और तरीका है कि सार्वजनिक कन्स्ट्रक्टर को डिफ़ॉल्ट मान के साथ घोषित करना है

 #define DEFAULT_CAR_INIT 0 Car::Car(int _no=DEFAULT_CAR_INIT); 

मुझे नहीं लगता है कि टाइप-सुरक्षित तरीका है जो कि आप क्या चाहते हैं।

आप इन-प्लेस ऑपरेटर का नया उपयोग कर सकते हैं यह थोड़ा भयानक होगा, और मैं एक कारखाने में रखने की सिफारिश करता था।

 Car* createCars(unsigned number) { if (number == 0 ) return 0; Car* cars = reinterpret_cast<Car*>(new char[sizeof(Car)* number]); for(unsigned carId = 0; carId != number; ++carId) { new(cars+carId) Car(carId); } return cars; } 

और एक इसी नष्ट को परिभाषित करें ताकि इस में उपयोग किए गए नए मैच के लिए हो सके।

मरे तरीके

 Car * cars; // else were extern Car * cars; void main() { // COLORS == id cars = new Car[3] { Car(BLUE), Car(RED), Car(GREEN) }; }