2011-04-25 17 views
7

मैं इस तरह एक वर्ग पदानुक्रम है:सी ++ सार क्लास के रूप में std :: मानचित्र कुंजी

std::map<Vehicle, double> prices; 
:

struct Vehicle { 
    virtual string model() = 0; // abstract 
    ... 
} 
struct Car : public Vehicle {...} 
struct Truck : public Vehicle {...} 

मैं कुछ जानकारी है कि मैं कुछ Vehicle उदाहरणों के बारे में प्राप्त के साथ एक std::map रखने की जरूरत है

हालांकि मुझे निम्न त्रुटि मिलती है:

/usr/include/c++/4.2.1/bits/stl_pair.h: In instantiation of ‘std::pair<const Vehicle, double>’: 
/usr/include/c++/4.2.1/bits/stl_map.h:349: instantiated from ‘_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = Vehicle, _Tp = double, _Compare = std::less<Vehicle>, _Alloc = std::allocator<std::pair<const Vehicle, double> >]’ 
test.cpp:10: instantiated from here 
/usr/include/c++/4.2.1/bits/stl_pair.h:73: error: cannot declare field ‘std::pair<const Vehicle, double>::first’ to be of abstract type ‘const Vehicle’ 
Model.hpp:28: note: because the following virtual functions are pure within ‘const Vehicle’: 
Model.hpp:32: note:  virtual string Vehicle::model() 

तो आप एक अमूर्त सीएल का उपयोग नहीं कर सकते std::map कुंजी के रूप में गधा। जहां तक ​​मैं यह कह सकता हूं क्योंकि नक्शा उनकी चाबियों की प्रतिलिपि बनाते हैं (कॉपी-कन्स्ट्रक्टर या असाइनमेंट ऑपरेटर के माध्यम से) और यह एक अमूर्त वर्ग (Vehicle) को तुरंत चालू करने का संकेत देगा। अगर आप भी कर सकते हैं, तो भी हम object slicing शिकार का शिकार करेंगे।

मुझे क्या करना चाहिए?

ऐसा लगता है मैं संकेत उपयोग नहीं कर सकते, क्योंकि वहाँ तार्किक समान Car या Truck के अलग प्रतियां हो सकता है। (यानी दो Car वस्तुओं अलग instantiated है, लेकिन जो एक ही कार और operator== रिटर्न सही प्रतिनिधित्व करते हैं। मैं इन std::map में एक ही वस्तु के लिए नक्शे की जरूरत है।)

+0

क्यों नहीं 'Vehicle' एक' price' सदस्य दे सकता है? या मॉडल नाम से मूल्य के लिए 'मानचित्र <स्ट्रिंग, डबल>' का उपयोग करें? – Beta

+0

@ बीटा नाटक करें यह एक दी गई खोज के लिए है (कहें, एक विशिष्ट भौगोलिक क्षेत्र में)। इसके अलावा यह bitwise-copies-synchronization समस्या हल नहीं करता है; अगर आपके पास 'कार' के दो उदाहरण हैं, तो केवल एक ही कीमत प्राप्त करेगा। –

+0

वास्तविक कारें पंजीकरण संख्या और एक अद्वितीय विनिर्माण धारावाहिक संख्या के साथ इसे हल करती हैं। –

उत्तर

10
  1. आपको Vehicle पर पॉइंटर्स का उपयोग करने की आवश्यकता है।

  2. operator==std::map द्वारा उपयोग नहीं किया जाता है, लेकिन एक तुलना करने वाला फ़ैक्टर जो std::map का तीसरा पैरामीटर है। डिफ़ॉल्ट रूप से यह std::less है।आप Vehicle साथ काम करने के अपने खुद के तुलना functor लागू करने की आवश्यकता:

    struct less_vehicle: std::binary_function<const Vehicle *, const Vehicle *, bool> 
    { 
        bool operator() (const Vehicle *a, const Vehicle *b) const { ... } 
    }; 
    

और फिर इसका इस्तेमाल:

std::map<Vehicle *, double, less_vehicle> 
1

आप संकेत का उपयोग करने के लिए, और एक टेम्पलेट तर्क उत्तीर्ण करनी होगी ऑब्जेक्ट के प्रकार को निर्दिष्ट करने के लिए जो तुलना करेगा (और जब आप नक्शा बनाते हैं, तो तुलना करने के लिए उस प्रकार का ऑब्जेक्ट पास करें)।

अपनी तुलना के लिए, आप चाहते हैं कि पॉइंटर्स को कम करें और उन वस्तुओं की तुलना करें जिन्हें वे इंगित करते हैं। हालांकि, यह भी ध्यान दें कि इसके लिए आपको कार और ट्रक के बीच कुछ प्रकार की तुलना परिभाषित करने की आवश्यकता होगी। यह जरूरी नहीं है कि यह विशेष रूप से सार्थक हो, लेकिन इसे लगातार और संक्रमणीय होना चाहिए (आधिकारिक शब्दावली यह है कि इसे "सख्त कमजोर आदेश" को परिभाषित करना होगा)।

+0

धन्यवाद जेरी। इसका मतलब है कि मुझे कक्षाओं को अलग करने की जरूरत है - यह आरटीटीआई करने का एकमात्र तरीका है? –

+0

@ एडम, आपको किसी रूप में आरटीटीआई की आवश्यकता होगी, अन्यथा कक्षाओं को डबल प्रेषण को लागू करने के लिए एक-दूसरे के बारे में जानना होगा। – Begemoth

1

आप एबीसी को एक कुंजी के रूप में उपयोग नहीं कर सकते हैं, क्योंकि एबीसी का उदाहरण होने पर कोई अर्थ नहीं होता है।

लाइन std::map<Vehicle, double> prices; तुम कह रहे हो, " Vehicle उदाहरणों कुंजी के रूप में के साथ एक नक्शा बनाने" के साथ

। चूंकि आपके पास Vehicle (जैसा कि यह शुद्ध वर्चुअल है) के उदाहरण नहीं हो सकते हैं, इसलिए आप उन्हें अपने मानचित्र में कुंजी के रूप में नहीं रख सकते हैं।

ऐसा कुछ नहीं है जिसे मैंने पहले से डब किया है, लेकिन मुझे लगता है कि map के साथ एक कस्टम आवंटक का उपयोग करके आप Vehicle पॉइंटर्स का उपयोग तर्कसंगत समान पॉइंट के लिए चेक के साथ कर सकते हैं।

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