Problem - Klasse mit String verbinden



  • Hallo!

    Ich mache folgendes, um eine neue Instanz einer Klasse über einen String aufzurufen:

    std::map<std::string,MyClass*> m_pCreate;
    m_pCreate.insert(std::make_pair("for",new MyClass()));
    
    // Neue Instanzen erstellen
    MyClass * pmc = m_pCreate["for"];
    MyClass * pmc1 = m_pCreate["for"];
    

    Das ganze funktioniert recht gut, nur das problem ist, das pmc und pmc1 auf das selbe objekt verweisen, d.h. wenn ich in pmc1 etwas ändere, so wird es auch in pmc geändert!
    Wie kann ich dieses Problem am besten beheben, ohne allzugroße Änderungen durchführen zu müssen?

    Danke,



  • Kopiere den Return-Wert und arbeite nicht mit Zeigern.

    Bsp:

    int main()
    {
        map<string, int> m;
        m.insert(make_pair("eins", 1));
        m.insert(make_pair("zwei", 2));
    
        int x = m["eins"]; // hier Kopie in x speichern.
    
        x = ...; // jetzt kannst du x verändern, ohne dass dies Auswirkungen auf m["eins"] hat.
    }
    

    Gruß Caipi



  • In der Map wird auf jeden Fall nur ein Objekt mit dem Index "for" drinstehen, da kannst du machen, was du willst - und jeder Zugriff auf m_pCreate["for"] wird dir genau dieses Objekt zurückgeben. Du könntest dir bestenfalls lokale Kopien des Objektes anlegen (geeigneter Copy-Ctor vorausgesetzt):

    MyClass mc1=*m_pCreate["for"];
    MyClass mc2=*m_pCreate["for"];
    //nun sind mc1 und mc2 lokale Kopien des Objekts "for" - und damit unabhängig von diesem (und voneinander)
    


  • Die Klasse "MyClass" ist ein Interface (abstract) und daher geht das mit dem copy-iterator nicht.



  • es ist ganz normal das bei verwendung einer map von zeigern die pointer mit gleichen namen auch auf die gleiche instanz zeigen

    also werden auch änderungen auch bei der _gleichen_ instanz, auf die mit einem _anderen_ pointer gezeigt wird "ankommen"

    ich denke du solltest dich etwas mit dem begriff factory auseinandersetzen, denn wirst du automatisch eine korrekte lösung finden

    es sollte etwa wie folgt aussehen:

    class MyClass{
    ....
    virtual MyClass* create();///< macht neue instanzen
    ...
    virtual ~MyClass();
    }
    
    class m_p_factory {
    
    map<sting,auto_ptr<MyCLass>> creators;// autoptr nimmt mit das ab, was normalerweise im dtor von m_p_factory steht
    
    void register(sting name,MyCLass* class)
    {
    creators.instert(PAIR(name,autoptr(class); //das ist kein korrektes c++, hätte sonst ctors für autoptr und so anschaun müssen ;P
    }
    MyClass* create(string name)
    {
    return creators[string]->create();
    }
    } // end class m_p_factory
    

    [edit]
    glaub jezze hab ich alle typo'S



  • Kurze Zwischenfrage: Wozu brauchst du eigentlich zwei unabhängige Kopien deines Objekts?



  • CStoll (off) schrieb:

    Kurze Zwischenfrage: Wozu brauchst du eigentlich zwei unabhängige Kopien deines Objekts?

    Ich habe ein skript in xml vorliegen.
    Also z.b.

    <for>
    ...
    </for>
    

    soll die Klasse mit dem Namen "for" aufrufen.



  • er will unabhängige instanzen, von ___verschiedenen___ klassen erzeugen
    also muss er die irgendwie erfragen



  • OK, wenn die direkte Zuweisung so nicht geht, schreib dir eine virtuelle Methode copy(), die jeweils eine Kopie deines Objektes anlegt:

    class base
    {
    public:
      ...
      base* copy() const = 0;
      ...
    }
    
    class forClass : public MyClass
    {
    public:
      forClass(const forClass& other) {...}
      ...
      base* copy() const
      {
        return new forClass(*this);
      }
      ...
    }
    
    map<string,base*> classes;
    classes.insert(make_pair("for",new forClass(...)));
    ...
    string input/* ="for" */;
    base* mc = classes[input].copy();
    


  • Danke für eure schnelle und kompetente hilfe 👍 .


Anmelden zum Antworten