2010-12-09 15 views
12

मैं आईडी की एक साहचर्य सरणी के रूप में एक नक्शा उपयोग कर रहा हूँ -> मूल्य, जहां मूल्य एक struct वस्तु को परिभाषित है:आप एक नक्शा कैसे शुरू करते हैं जो संरचना के रूप में मूल्य लेता है?

#include <map> 

struct category { 
     int id; 
     std::string name; 
}; 

std::map<int, category> categories; 

int main() { 
     categories[1] = {1, "First category"}; 
     categories[2] = {2, "Second category"}; 

} 

ऊपर कोड जी के साथ ++ संकलित है, लेकिन निम्न चेतावनी के साथ:

warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x 

मैंने संरचना प्रारंभिकरण के बारे में यहां विभिन्न प्रश्न/उत्तर पढ़े हैं, लेकिन मैं अभी भी थोड़ा उलझन में हूं।

  1. मैं संकलक विकल्प -std = C++ 0x जोड़ सकता है और चेतावनी के साथ किया जा, लेकिन फिर भी कोई भी मूल समस्या के बारे में समझदार हो: मैं संबंधित प्रश्नों की एक श्रृंखला है। यदि मैं श्रेणी संरचना में कोई विधि जोड़ता हूं तो चीजें तोड़ नहीं जाएंगी?

  2. इस पीओडी संरचना (श्रेणी) को और अधिक C++ 03 अनुरूप तरीके से शुरू करने का सबसे अच्छा तरीका क्या होगा?

  3. असल में, मुझे अभी तक किसी अन्य तरीके से चीजों को करने का नतीजा नहीं है। इस प्रकार की एसोसिएटिव सरणी (जहां कुंजी किसी ऑब्जेक्ट की आईडी है) PHP के साथ आसान है, और मैं अभी भी सी ++ में ऐसा करने के उचित तरीके के बारे में सीख रहा हूं। क्या उपरोक्त कोड के संदर्भ में मुझे कुछ भी ध्यान देना चाहिए?

संपादित
निम्न प्रश्नों से संबंधित हैं, लेकिन मैं जवाब समझ में नहीं आया जब मैंने पहली बार उन्हें पढ़ने:
C++ initialize anonymous struct
c++ Initializing a struct with an array as a member
Initializing structs in C++

उत्तर

17

सी ++ (आईएसओ/आईईसी 14882: 2003) में, अभिव्यक्तियों की एक ब्रेस संलग्न सूची का उपयोग कुल के वैरिएबल को शुरू करने के लिए किया जा सकता है, जो इसे परिभाषित करता है।

उदा।

struct S { int a; std::string b; }; 

S x = { 39, "Hello, World\n" }; 

एक कुल प्रकार किसी सरणी या कोई उपयोगकर्ता के घोषित कंस्ट्रक्टर्स, कोई निजी या संरक्षित गैर स्थिर डेटा सदस्यों, कोई आधार वर्ग है, और कोई आभासी कार्यों के साथ एक वर्ग है। ध्यान दें कि एक वर्ग कुल को पीओडी-क्लास नहीं होना चाहिए और कोई भी सरणी कुल है या नहीं, यह प्रकार एक सरणी है या नहीं।

हालांकि, अभिव्यक्तियों की एक ब्रेस-संलग्न सूची केवल कुल के लिए प्रारंभकर्ता के रूप में मान्य है, इसे आमतौर पर असाइनमेंट या क्लास कन्स्ट्रक्टर के सदस्य प्रारंभिक सूची जैसे अन्य संदर्भों में अनुमति नहीं दी जाती है।

सी के ++ (C++ 0x) अगले संस्करण, अभिव्यक्ति की एक ब्रेस संलग्न सूची (ब्रेस-init-सूची) के मौजूदा मसौदे में अधिक संदर्भों में अनुमति दी है और जब एक वस्तु इस तरह के एक से आरंभ नहीं हो जाता प्रारंभकर्ता सूची इसे सूची-प्रारंभिकरण कहा जाता है।

नए संदर्भ जहां ऐसी सूची की अनुमति है, में फ़ंक्शन कॉल, फ़ंक्शन रिटर्न, कन्स्ट्रक्टर के लिए तर्क, सदस्य और आधार प्रारंभकर्ता और असाइनमेंट के दाईं ओर शामिल तर्क शामिल हैं।

इसका मतलब है कि यह C++ 03 में मान्य नहीं है।

int main() { 
     categories[1] = {1, "First category"}; 
     categories[2] = {2, "Second category"}; 
} 

इसके बजाय आप ऐसा कुछ कर सकते हैं।

int main() { 
     category tmp1 = { 1, "First category" }; 
     category tmp2 = { 2, "Second category" }; 

     categories[1] = tmp1; 
     categories[2] = tmp2; 
} 

वैकल्पिक रूप से।

int main() { 
     category tmpinit[] = { { 1, "First category" }, 
           { 2, "Second category" } }; 
     categories[1] = tmpinit[0]; 
     categories[2] = tmpinit[1]; 
} 

या, आप अपने प्रकार के लिए फ़ैक्टरी फ़ंक्शन बनाने पर विचार कर सकते हैं। (आप अपने प्रकार के लिए एक कन्स्ट्रक्टर जोड़ सकते हैं लेकिन यह आपकी कक्षा को गैर-योगित करेगा और आपको अन्य स्थानों में कुल प्रारंभिक उपयोग करने से रोक देगा।)

category MakeCategory(int n, const char* s) 
{ 
    category c = { n, s }; 
    return c; 
} 

int main() 
{ 
    categories[1] = MakeCategory(1, "First category"); 
    categories[2] = MakeCategory(2, "Second category"); 
} 
+0

आखिर में कोई भी जो इसे ठीक से मिला है। धन्यवाद, चार्ल्स! – sbi

+0

पूरी चर्चा को सारांशित करने के लिए समय लेने के लिए @ चार्ल्स बेली धन्यवाद। इस आगे बढ़ने के लिए @ एसबीआई धन्यवाद। मैं इसकी बहुत सराहना करता हूं। :) – augustin

+0

बीटीडब्ल्यू, प्रश्न का शीर्षक अंततः चर्चा की सामग्री को प्रतिबिंबित नहीं करता है।प्रश्न के शीर्षक को संपादित करने के लिए स्वतंत्र महसूस करें जो अधिक उपयुक्त होगा। – augustin

10

वर्तमान C++ मानक , आप केवल पीओडी मान वाले सरणी और structs को प्रारंभ करने के लिए प्रारंभकर्ता सूचियों का उपयोग कर सकते हैं। अगला मानक (उर्फ सी ++ 0x या सी ++ 1 एक्स) गैर-पीओडी प्रकार वाले structs पर ऐसा करने की अनुमति देगा, उदा। std :: स्ट्रिंग। यही चेतावनी है।

#include <map> 
#include <string> 

struct category { 
     category() : id(0), name() {} 
     category(int newId, std::string newName) 
     : id(newId), name(newName) {} 

     int id; 
     std::string name; 
}; 

std::map<int, category> categories; 

int main() { 
     categories[1] = category(1, "First category"); 
     categories[2] = category(2, "Second category"); 

} 
+0

+1, धन्यवाद। यह इस तरह से काम करता है। आश्चर्यजनक रूप से, अगर मैं खाली नियंत्रक श्रेणी :: श्रेणी() के साथ लाइन को छोड़ देता हूं तो कोड संकलित नहीं होता है।स्पष्ट रूप से नक्शा तुलनात्मक उद्देश्यों के लिए इसकी आवश्यकता है: /usr/include/c++/4.4/bits/stl_map.h:450: त्रुटि: 'श्रेणी :: श्रेणी()' – augustin

+3

पर कॉल के लिए कोई मिलान करने वाला फ़ंक्शन यह अजीब नहीं है, लेकिन मानक व्यवहार । किसी भी प्रकार जिसे आप एक एसटीएल कंटेनर के अंदर स्टोर करना चाहते हैं उसे एक डिफ़ॉल्ट कन्स्ट्रक्टर की आवश्यकता होती है। और किसी भी कन्स्ट्रक्टर के बिना कक्षाएं और structs स्वचालित रूप से एक मिलता है, लेकिन जैसे ही आप अपना खुद का परिभाषित करते हैं, आपको भी एक डिफ़ॉल्ट को परिभाषित करना होगा। – Mephane

+0

ओह, मैं देखता हूं। स्पष्ट स्पष्टीकरण के लिए धन्यवाद। :) – augustin

3

आरंभीकरण हम प्रयोग कर रहे हैं उभरते सी में केवल शुरू की है की तरह ++ मानक:

मैं तुम्हें category कि आईडी और नाम लेता है और बस के बजाय कि निर्माता कॉल करने के लिए एक सरल निर्माता जोड़ने सुझाव देंगे सी ++ 0x कहा जाता है, इसलिए चेतावनी और संकलक विकल्प। जी ++ के रूप में कुछ कंपाइलर्स पहले से ही कुछ नई सुविधाओं का समर्थन करते हैं, लेकिन मानक स्वयं को अभी तक स्वीकार नहीं किया गया है। यह सी ++ में कई नई विशेषताएं जोड़ता है जैसा कि हम जानते हैं। आप Stroustrup's site पर और पढ़ सकते हैं।

संरचना को आरंभ करने के लिए आप एक ctor (स्वाभाविक रूप से) जोड़ सकते हैं, उदा।

struct category { 
     category(int i, const std::string& n): id(i), name(n) {} 
     int id; 
     std::string name; 
}; 

और फिर नक्शा प्रारंभ करने में इस प्रकार है:

categories[1] = category(1, "First category"); 

ध्यान दें कि स्ट्रिंग के लिए const char* से एक अंतर्निहित रूपांतरण यहाँ काम करेंगे, वरना आप const char* भी साथ एक ctor परिभाषित कर सकते हैं।

+0

और मेफेन ने एक ही जवाब के बारे में 1 मिनट अलग किया। जवाब वही है, लेकिन खाली कन्स्ट्रक्टर के लिए, और कोड इसके बिना संकलित नहीं होगा। मेफेन के जवाब में मेरी टिप्पणी देखें। किसी भी मामले में, यह पुष्टि करता है कि एक कन्स्ट्रक्टर का उपयोग करने का तरीका है। धन्यवाद। (और +1) – augustin

+0

@augustin: सही खाली खाली सीटीओआर। एक नोट, मैं अस्थायी स्मृति आवंटन और प्रतिलिपि से बचने के लिए 'std :: string n' पर 'const std :: string & n' से गुजरने वाले कॉन्स्ट रेफ पैरामीटर को प्राथमिकता दूंगा। और स्वीकृति के लिए धन्यवाद :) – davka

+0

const std :: string & n के बारे में अच्छा बिंदु। और आपकी मदद के लिए धन्यवाद। – augustin

1

आपको जिस सुविधा की आवश्यकता है उसे कुल सी/सी ++ में समझा जाता है।"कुल सी ++" खोजकर, आपको whys और hows का विवरण देने वाली बहुत सारी जानकारी मिल जाएगी।

1- Wouldn't things break if I add a method to the category struct?

जब तक विधि अंतर्निहित सी ++ मेमोरी लेआउट को प्रभावित नहीं करती तब तक आवश्यक नहीं है। उदाहरण के लिए, एक सादा फ़ंक्शन कोई फर्क नहीं पड़ता, लेकिन वर्चुअल फ़ंक्शन होगा क्योंकि यह कक्षा के सदस्यों के सामने संभवतः निर्धारित किया गया है।

2- What would the best way be to initialize this POD struct (category) in a more c99 compliant way?

अन्य उत्तरदाताओं के रूप में रचनाकारों का उपयोग करते हुए सुझाव देते हैं।

3- Is there anything I should pay attention to in the context of the code above?

इसमें आप कन्स्ट्रक्टर को डिज़ाइन करने के तरीके के आधार पर अनावश्यक प्रतियां शामिल कर सकते हैं। लेकिन यह केवल तभी महत्वपूर्ण है जब आपको अक्सर प्रारंभिकरण की आवश्यकता होती है और आप वास्तव में प्रदर्शन की परवाह करते हैं।

+0

+1, धन्यवाद। यह मेरे लिए कुछ नया है, और जैसा कि आप सुझाव देते हैं, मैं इसे अभी देख रहा हूं। – augustin

+0

आपके सुझाव के लिए धन्यवाद, मुझे यह उपयोगी पृष्ठ पुनः मिला। कुल प्रारंभिकरण: http://www.codeguru.com/cpp/tic/tic0077.shtml – augustin

+0

और यह भी: http://en.wikipedia.org/wiki/C++_classes – augustin

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