CString* als void* übergeben und zerstören



  • Ich habe ein Problem mit einem CString-Zeiger. Ich übergebe diesen an eine Methode als void-Zeiger, da auch int-Zeiger an diese Methode übergeben werden können sollen.

    Nun ist es so, dass die Methode diese Zeiger auch löscht bzw. den reservierten Platz wieder freigibt. Beim int klappt das, wenn ich jedoch einen CString übergebe bekomme ich "Dumping objects ->" :(.

    Der Code sieht zusammengefasst so aus:

    void CListe::Add(void* pZeiger) {
      // Hier wird der Zeiger in eine Liste hinzugefügt
      m_Liste.insert(m_Liste->begin(), pZeiger);
    }
    
    CListe::~CListe() {
      // Alle Elemente in der Liste zerstören
      ...
        delete m_Liste[i];
      ...
    }
    
    // So klappt es
    int* pInt = new int(5);
    Add(pInt);
    
    // Das klappt nicht bzw. führt zu "Dumping objects ->"
    CString* pString = new CString("Test");
    Add(pString);
    

    Geht das nicht mit Objekten, weil der Voidzeiger nicht die nötigen Informationen hat, wie er den CString zu zerstören hat? Oder geht das irgendwie bzw. mach ich etwas falsch?



  • Der Pointer kann nicht wissen ob er auf ein CString Objekt oder einen int zeigt.
    Beim Zerstören müsstest du dann erstmal rausfinden, welcher Zeiger auf was zeigt und dann entsprechend zerstören. Sonst wird einfach nur ein 32Bit irgendwas vernichtet.

    Pseudocode:

    if (isteinint)
        delete (int*)pInt;
    if (istCString)
        delete (CString*)pString;
    


  • Davon abgesehen ist das design-technisch totaler Quatsch...



  • Davon abgesehen ist das design-technisch totaler Quatsch...

    Ich bin für jegliche design-technische Ideen offen 🙂



  • Ich habe keine Ahnung, was du machen willst 😉



  • Beliebige Daten (bzw. Pointer) in einem "Sammelcontainer" ablegen :). Beim zerstören des Containers werden dann auch die Daten gelöscht. Dabei weiß ich nicht, um welche Daten es sich handelt. 🙂



  • Kann man das auch durcheinanderwürfeln?

    Also:

    cont.Add(3);
    cont.Add("lalala");
    

    😕



  • @erik:
    Was ist der Sinn von soetwas?



  • Zum Ablegen beliebiger Allesmögliche-Pointer gibt es übrigens auch die Klasse CObArray 😉 Aber dEUs hat Recht: Was willst du damit überhaupt erreichen?



  • Der Sinn ist schnell erklärt. Austausch von Objekten über eine Datenlagerstelle. Zwei Prozesse ändern Objekte ab, andere Prozesse lesen die Daten die sie interessieren aus. Alle Daten sollen zentral gelagert werden, so dass auch spätere Programmodule (lediglich über den Header) diese Daten in der zentralen Ablage auslesen oder manipulieren können.

    Ich habs jetzt ein wenig anders gelöst und es funktioniert :). Ich hab einfach eine Klasse definiert die ich CDaten genannt habe. Nun muss jedes Objekt - welches in den Container soll - von einer Klasse sein, die von CDaten geerbt hat. Der Destruktor von CDaten ist natürlich virtual :).

    Für CString hab ich dann gleich ne Klasse geschrieben 🙂

    class CDaten
    {
    public:
    	CDaten() {};
    	virtual ~CDaten() {};
    }
    
    class CSTRDaten : public CDaten
    {
    public:
    	CSTRDaten (CString sVal) { m_sVal = sVal; };
    	~CSTRDaten () {};
    	CString m_sVal;
    };
    

    Die lesende Schnittstelle liest nun die Daten aus dem "zentralen Lager" aus und castet diese mit einem dynamic_cast. Der Lesende weiß ja was für Daten er von dem Lager erwartet :).

    Ich weiß nicht ob die Lösung jetzt besser ist, aber ich hoffe es doch :). Ich hoffe ich habe euch mit meiner Idee nicht zu lange aufgehalten :).



  • Und so funktioniert auch das erwähnte CObArray. 😃



  • Und so funktioniert auch das erwähnte CObArray...

    ... da frag ich mich jetzt: Ist das gut oder schlecht? 😃



  • Gute Frage. 😃

    Nur für den Fall, dass du das Rad nicht neu erfinden willst/sollst, solltest du dich damit genauer beschäftigen. 😉



  • Nur für den Fall, dass du das Rad nicht neu erfinden willst/sollst, solltest du dich damit genauer beschäftigen.

    Werde ich auch machen :). Danke auf jedenfall für den Hinweis das es das schon gibt ;).



  • Mein Tip: verwende eine map (z.B. std::map<>) die als Value boost::shared_ptrboost::any hat. Dadurch bekommst du auch automatisch type safety beim auslesen.

    Oder aber stecke deine Objekte in einen selbst geschriebenen Wrapper, ala so:

    class AnyThing
    {
    public:
        virtual ~AnyThing() {}
    };
    
    template <class T> class Thing : public AnyThing
    {
    public:
        Thing(T const& t)
            : m_t(t)
        {}
    
        T& Get() { return m_t; }
        T const& Get() const { return m_t; }
    
    private:
        T m_t;
    };
    

Anmelden zum Antworten