2011-12-11 25 views
14

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

MyClass *myVar; 
myVar = new MyClass[num]; // I would like to specify the array size after declaration 
int i = 0; 
for(i = 0;i < num;i++) 
    myVar[i] = new MyClass(0,0); // I would also like to populate the array with new objects 

मुझे पता है कि यह काम करता है:: मैं कुछ इस तरह चाहते

MyClass *myVar; 
myVar = new MyClass[num]; 

लेकिन यह केवल काम करता है जब निर्माता कुछ भी नहीं है इसे में पारित कर दिया। क्या मैं संभव करने की कोशिश कर रहा हूं? यदि ऐसा है, तो मुझे इसे कैसे करना है?

संपादित करें: मुझे पता चला कैसे सरणियों उपयोग करने के साथ यह करने के लिए। यहाँ है कैसे मैंने किया:

MyClass **myVar; 
myVar = new MyClass *[num]; 
for(i = 0;i < num;i++) 
    myVar[0] = new MyClass(0,0); 

मैं वैक्टर और इस तरह का प्रयोग करेंगे, लेकिन मेरे शिक्षक बुनियादी सरणियों जब भी संभव हो उपयोग करने के लिए हमें बताया गया है। उपरोक्त समाधान मैं वास्तव में मेरे शिक्षक ने लिखा कुछ कोड से मिला है। आपकी मदद के लिए आप सभी को शुक्रिया!

उत्तर

21
MyClass *myVar; 
myVar = new MyClass[num]; 

दरअसल इस रूप में आप निर्माता को नहीं ले सकते हैं जो पैरामीटर लेता है। भाषा विनिर्देशन द्वारा इसकी अनुमति नहीं है।

#include <vector> //header file where std::vector is defined 

std::vector<MyClass> arr(num, MyClass(10,20)); 

यह num तत्वों का एक वेक्टर बनाता है, प्रत्येक तत्व बनाई गई है:

हालांकि, अगर आप std::vector, जो मैं आप का उपयोग करने की सलाह देते उपयोग करते हैं, तो आप एक वेक्टर गैर-डिफ़ॉल्ट निर्माता बुला के रूप में बना सकते हैं कक्षा के प्रति-निर्माता को कॉल करके, MyClass(10,20) को इसके तर्क के रूप में गुज़रने के द्वारा।

वेक्टर क्योंकि अब आप न स्मृति अपने आप को प्रबंधित करने की आवश्यकता भी अच्छा है। न तो मैन्युअल आवंटन, न ही मैन्युअल deallocation। इसके अलावा, आप किसी भी समय arr.size() फोन करके तत्वों की संख्या पता कर सकते हैं। आप हमेशा जानते हैं कि वेक्टर में कितने तत्व हैं। वैसे ही जैसे आप का उपयोग सरणी,

arr.push_back(MyClass(20,30)); 

और अब आप तत्वों का उपयोग कर सकते, सूचकांक का उपयोग करके अर्थात्:: आप कभी भी तत्व जोड़ सकते हैं, बस .push_back() सदस्य प्रकार्य को बुलाने से ही

f(arr[i]); // 0 <= i < arr.size(); 

, आप iterators जो मुहावरेदार प्रोग्रामिंग की सुविधा का उपयोग कर सकते हैं, तो आप के रूप में <algorithm> हैडर से विभिन्न एल्गोरिथम कार्यों का उपयोग करने के लिए सक्षम:

#include <algorithm> //header file where std::for_each is defined 

std::for_each(arr.begin(), arr.end(), f); 

wher ई f समारोह किस प्रकार MyClass& (या MyClass const &) में से एक तर्क है कि तुम क्या f में क्या करना चाहते हैं पर निर्भर करता है लेता है।

सी ++ 11 में, आप के रूप में लैम्ब्डा उपयोग कर सकते हैं:

std::for_each(arr.begin(), arr.end(), [](const MyClass & m) 
             { 
              //working with m 
             }); 
+1

धन्यवाद! मैं वास्तव में वैक्टरों के बजाय सरणी का उपयोग करके एक दृष्टिकोण की तलाश में था क्योंकि मेरा शिक्षक वर्ग को इसके बजाय सरणी का उपयोग करना चाहता था। हालांकि मुझे जवाब मिला। – user972276

+0

@ user972276: यदि आप गैर-डिफ़ॉल्ट कन्स्ट्रक्टर का आह्वान करना चाहते हैं तो एरे के लिए आपका पहला दृष्टिकोण यह है कि कोई क्या कर सकता है। हालांकि, भविष्य में, यदि आपको कभी भी सरणी की आवश्यकता है, * पहले * 'std :: vector' का उपयोग करने पर विचार करें। यह बहुत बढ़िया फीचर के साथ एक शानदार कंटेनर है। – Nawaz

6

C++ 0x में, यह व्याकरण काम करता है, जो नए अभिव्यक्ति में गैर-डिफ़ॉल्ट निर्माता कॉल कर सकते हैं:

MyClass *myVar; 
myVar = new MyClass[2]{{10, 20},{20, 30}}; 

लेकिन मुझे शक है अगर यह काम करता है जब केवल रन टाइम पर उपलब्ध में तत्वों की संख्या।

नवाज के उत्तर में दिखाए गए अनुसार वेक्टर दृष्टिकोण बेहतर होगा।

2

एक तरह से मैंने इसे पहले किया है एक डबल पॉइंटर का उपयोग कर रहा है। काफी किसी भी नियंत्रण संरचना आप कल्पना कर सकते साथ

MyClass ** myvar; 
myvar = new Myclass*[num] 
for(int i = 0; i < 4; i++){ 
*(myvar+i) = new Myclass(i);} 

काम करता है, केवल झटका है कि वस्तुओं जरूरी ढेर पर लगातार होने जा रहा नहीं कर रहे हैं।

0

असल में, आप इस संभाल करने के लिए एक प्लेसमेंट नई उपयोग कर सकते हैं:

MyClass * myVar; 
myVar = reinterpret_cast<MyClass *>(new char[num * sizeof(MyClass)]); 
int i = 0; 
for (i = 0; i < num; i++) { 
    new(&myVar[i]) MyClass(0,0); 
} 
+0

आपको 'new char []' के बजाय 'std :: aligned_storage' का उपयोग करना चाहिए। –

+0

यह भी उल्लेख किया जाना चाहिए कि इस मेमोरी को मुक्त करने के लिए आपको प्रत्येक ऑब्जेक्ट के विनाशकों के माध्यम से लूप करना होगा और फिर 'हटाएं [] reinterpret_cast (myVar) को कॉल करना होगा; '। –

0

आप इस तरह कुछ भी कर सकते हैं: आपकी मदद के लिए

MyClass *myVar[num]; 

for(int i = 0; i < num; i += 1) 
{ 
    myVar[i] = new MyClass(0, 0); 
} 
संबंधित मुद्दे