2010-10-24 16 views
12

मान लें कि मेरे पास कक्षा बॉक्स है, और उपयोगकर्ता बॉक्स बना सकता है। यह कैसे करना है? मैं समझता हूं कि मैं className objectName(args); द्वारा ऑब्जेक्ट्स बना सकता हूं लेकिन उपयोगकर्ता इनपुट के आधार पर गतिशील रूप से इसे कैसे किया जाए?कक्षा वस्तुओं को गतिशील रूप से कैसे बनाएं?

class BoxFactory 
{ 
    public: 
    static Box *newBox(const std::string &description) 
    { 
     if (description == "pretty big box") 
     return new PrettyBigBox; 
     if (description == "small box") 
     return new SmallBox; 
     return 0; 
    } 
}; 
बेशक

, PrettyBigBox और SmallBox दोनों Box से निकाले जाते हैं:

+3

क्या आप एक (संभावित रूप से छद्म कोड) कोड उदाहरण दे सकते हैं? –

+0

उन्हें कहां बनाएँ? उदाहरण के लिए, आप उन्हें 'std :: vector' में स्टोर कर सकते हैं, लेकिन यह वास्तव में निर्भर करता है कि आप क्या कर रहे हैं। – GManNickG

+0

दुर्भाग्य से सी ++ में आप गतिशील रूप से एक कन्स्ट्रक्टर को कॉल नहीं कर सकते हैं। एकमात्र तरीका उन वस्तुओं को स्टोर करना है जो रनटाइम पर आप जो चाहते हैं उसकी एक नई निर्मित वस्तु वापस करने में सक्षम हैं। आपके द्वारा पहले से प्राप्त किए गए उदाहरण उत्तर पूरी तरह से प्रासंगिक हैं। –

उत्तर

5

निम्नलिखित कारखाने विधि Box उदाहरणों गतिशील उपयोगकर्ता इनपुट के आधार पर बनाता है। C++ design patterns wikibook में रचनात्मक पैटर्न पर नज़र डालें, क्योंकि उनमें से एक शायद आपकी समस्या पर लागू होता है।

2

सी ++ में, स्वचालित (ढेर) और गतिशील (ढेर) भंडारण का उपयोग करके ऑब्जेक्ट आवंटित करना संभव है।

#include <cstdlib> 
#include <iostream> 
#include <memory> 
class Base { 
    public: 
     virtual ~Base(){} 
     virtual void printMe() const = 0; 
    protected: 
     Base(){} 
}; 
class Alpha : public Base { 
    public: 
     Alpha() {} 
     virtual ~Alpha() {} 
     virtual void printMe() const { std::cout << "Alpha" << std::endl; } 
}; 
class Bravo : public Base { 
    public: 
     Bravo() {} 
     virtual ~Bravo() {} 
     virtual void printMe() const { std::cout << "Bravo" << std::endl; } 
}; 
int main(int argc, char* argv[]) { 
    std::auto_ptr<Base> pointer; // it is generally better to use boost::unique_ptr, 
           // but I'll use this in case you aren't familiar 
           // with Boost so you can get up and running. 
    std::string which; 
    std::cout << "Alpha or bravo?" << std::endl; 
    std::cin >> which; 
    if (which == "alpha") { 
     pointer.reset(new Alpha); 
    } else if (which == "bravo") { 
     pointer.reset(new Bravo); 
    } else { 
     std::cerr << "Must specify \"alpha\" or \"bravo\"" << std::endl; 
     std::exit(1); 
    } 
    pointer->printMe(); 
    return 0; 
} 

संबंधित:

Type variable_name; // variable_name has "automatic" storage. 
        // it is a local variable and is created on the stack. 

Type* pointer_name = NULL; // pointer_name is a "pointer". The pointer, itself, 
          // is a local variable just like variable_name 
          // and is also created on the stack. Currently it 
          // points to NULL. 

pointer_name = new DerivedType; // (where DerivedType inherits from Type). Now 
           // pointer_name points to an object with 
           // "dynamic" storage that exists on the heap. 

delete pointer_name; // The object pointed-to is deallocated. 
pointer_name = NULL; // Resetting to NULL prevents dangling-pointer errors. 

आप डायनामिक रूप में के रूप में वस्तुओं का निर्माण करने के संकेत दिए गए और ढेर-आवंटन का उपयोग कर सकते the "Factory" object-oriented design pattern

15

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

यदि संख्या बड़ी है (एप्लिकेशन आपके आवेदन में किसी भी वर्ग का उदाहरण बनाने में सक्षम होना चाहिए), तो आपको .Net की प्रतिबिंब कार्यक्षमता का उपयोग करना चाहिए। लेकिन, ईमानदार होने के लिए, मैं व्यवसाय तर्क में प्रतिबिंब का उपयोग करने का बड़ा प्रशंसक नहीं हूं, इसलिए मैं ऐसा करने की सलाह नहीं दूंगा।

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

class Animal {...}; 
class Dog : public Animal {...} 
class Cat : public Animal {...} 

फिर जो एक अंतरफलक है एक सार कारखाना बनाने कि एक जानवर बनाता है:

class IFactory 
    { 
    public: 
     Animal *create() = 0; 
    }; 

फिर विभिन्न प्रकार के जानवरों के लिए उप-वर्ग बनाएं। जैसे कुत्ते वर्ग के लिए यह बन जाएगा:

class DogFactory : public IFactory 
    { 
    public: 
     Dog *create() {return new Dog();} 
    }; 

और बिल्ली के लिए भी यही है।

डॉगफैक्टरी :: बनाने की विधि IFactory :: बनाने की विधि को ओवरराल करती है, भले ही उनका रिटर्न टाइप अलग हो। यही सह-संस्करण वापसी प्रकार कहा जाता है। जब तक उप-वर्ग की विधि का रिटर्न प्रकार बेस क्लास के रिटर्न प्रकार का उप-वर्ग होता है, तब तक इसकी अनुमति है।सही कारखाना मिल जाए, और उदाहरण बनाने के लिए इसका पूछने के लिए

typedef std::map<char *,IFactory *> AnimalFactories 
AnimalFactories animalFactories; 
animalFactories["Dog"] = new DogFactory(); 
animalFactories["Cat"] = new CatFactory(); 

उपयोगकर्ता इनपुट के बाद, आप है:

अब आप क्या कर सकते हैं किसी नक्शे में इन सभी कारखानों के उदाहरण डाल दिया जाता है, इस तरह जानवर का:

AnimalFactories::const_iterator it=animalFactories.find(userinput); 
if (it!=animalFactories.end()) 
    { 
    IFactory *factory = *it; 
    Animal *animal = factory->create(); 
    ... 
    } 

यह ठेठ अमूर्त कारखाना दृष्टिकोण है। अन्य दृष्टिकोण भी हैं। खुद को सी ++ पढ़ाने के दौरान मैंने इसके बारे में एक छोटा कोडप्रोजेक्ट आलेख लिखा था। आप इसे यहां पा सकते हैं: http://www.codeproject.com/KB/architecture/all_kinds_of_factories.aspx

शुभकामनाएं।

0

वेक्टर का उपयोग करने का एक आसान तरीका है। पहले, वेक्टर लाइब्रेरी शामिल करें और अपनी कक्षा के रूप में एक अस्थायी वस्तु बनाएं।

class temp; 

तो, अपने वर्ग के प्रकार के साथ उदाहरण नामित वस्तुओं के लिए एक वेक्टर बनाने:

#include <vector> 
. 
. 
vector <class>objects; 

तो आप एक object.for उदाहरण जोड़ने के लिए एक पाश में जोड़ सकते हैं, मैं एक वर्ग नामित अस्थायी है कि है इनपुट नामक एक फ़ंक्शन और मैं जोड़ना चाहता हूं:

while(1){ 
     temp.input(); 
     objects.push_back(temp); 
     } 

अब आपके पास गतिशील वर्ग है। अपने वस्तुओं के लिए उपयोग करने के लिए आप इस तरह से उपयोग कर सकते हैं:

objects[i]; 

और यदि आप एक वस्तु को नष्ट करना चाहते हैं, बस इस तरह का उपयोग करें: 1.Find वेक्टर में अपनी वस्तु स्थान। उस के साथ अपने वेक्टर के अंतिम ब्लॉक के 2.change राशि और अंतिम ब्लॉक निकालें:

int lastblock; 
lastblock=(objects.size()-1); 
:

objects[location of the object you want to remove]=objects[location of your last block]; 
objects.pop_back(); 

अगर आप अपने वेक्टर के अंतिम ब्लॉक के स्थान पता करने के लिए ऐसा करने के लिए चाहते हैं

नोट: आप एक सरणी जैसे वैक्टर का उपयोग कर सकते हैं।

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