2017-08-17 23 views
5

जावा में आप एक मानचित्र बना सकते हैं जो स्ट्रिंग टू जेनेरिक ऑब्जेक्ट प्रकारों को मानचित्रित कर सकता है जिसे स्पष्ट रूप से अन्य वर्गों में डाला जा सकता है। क्या सी ++ में इस कार्यक्षमता का अनुकरण करने का कोई अच्छा तरीका है?सी ++ जावा मानचित्र के समतुल्य <स्ट्रिंग, ऑब्जेक्ट>

+0

सी ++ 11/14, std :: map में कोई नक्शा है। कृपया जांचें कि क्या यह आपकी आवश्यकता को पूरा कर सकता है। – tibetty

+0

और ['std :: unordered_map'] (http://en.cppreference.com/w/cpp/container/unordered_map) –

+1

मुझे लगता है कि ओप एक वर्ग ऑब्जेक्ट के बारे में बात कर रहा है जो किसी भी प्रकार की वस्तु को स्वीकार कर सकता है ... डेटा कंटेनर संग्रह के बारे में नहीं मानचित्र –

उत्तर

1

काफी दृढ़ता से टाइप की गई भाषा होने के नाते, सी ++ में "जेनेरिक ऑब्जेक्ट टाइप" नहीं है। इसमें निश्चित रूप से सहयोगी कंटेनर हैं: std::map (बाइनरी पेड़ का स्वाद) और std::unordered_map (हैश टेबल का स्वाद)। जो बेहतर है उपयोग के मामले पर निर्भर करता है, और अक्सर प्रोफाइलिंग के बिना तय नहीं किया जा सकता है।

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

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

#include <unordered_map> 
#include <string> 
#include <memory> // std::unique_ptr<>, std::make_unique() 
#include <iostream> 

class NotSoGenericClass { 
    public: 
    virtual ~NotSoGenericClass() = default; 
    virtual std::string name() const 
    { return "NotTooGenericClass()"; } 
}; 

class EvenLessGenericClass: public NotSoGenericClass { 
    int fValue = 0; 
    public: 
    EvenLessGenericClass(int value): fValue(value) {} 
    virtual std::string name() const override 
    { return "EvenLessGenericClass(" + std::to_string(fValue) + ")"; } 
    int value() const { return fValue; } 
}; 

int main() { 
    // 
    // map holding (and owning) "not so generic objects" 
    // 
    std::unordered_map<std::string, std::unique_ptr<NotSoGenericClass>> allObjects; 

    // 
    // populate it 
    // 
    allObjects["any"] = std::make_unique<NotSoGenericClass>(); 
    allObjects["six"] = std::make_unique<EvenLessGenericClass>(6); 
    allObjects["one"] = std::make_unique<EvenLessGenericClass>(1); 

    std::cout << "Object 'six' says: " << allObjects["six"]->name() << std::endl; 

    std::cout << "Now dumping all " << allObjects.size() << " objects:"; 
    for (auto const& keyAndObject: allObjects) { 

    auto const& key = keyAndObject.first; 
    auto const* object = keyAndObject.second.get(); 

    // 
    // base class interface is always available: 
    // 
    std::cout << "\n[" << key << "] " << object->name(); 

    // 
    // object-specific one requires a cast: 
    // 
    auto const* lessGen = dynamic_cast<EvenLessGenericClass const*>(object); 
    if (lessGen) std::cout << " (value is " << lessGen->value() << ")"; 

    } // for 
    std::cout << std::endl; 

    return 0; 
} // main() 

मेरी मंच पर, इस कोड (का उपयोग करते हुए सी ++ 14) का उत्सर्जन करता है:

[one] EvenLessGenericClass(1) (value is 1) 
[six] EvenLessGenericClass(6) (value is 6) 
[any] NotTooGenericClass() 

(भी "अव्यवस्थित" नक्शा नाम के अर्थ को दर्शाता हुआ)। यह उदाहरण g++ -Wall -pedantic -std=c++14 -o test.exe test.cpp (जीसीसी 6.4.0) के साथ संकलित किया गया था।

2

सी ++ में आप std :: मानचित्र < std :: string, std :: any > का उपयोग कर सकते हैं।

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