auto_ptr und stackobjektzuweisung gültig?



  • Tachyon schrieb:

    Normalerweise weiss man schon selbst, ob man Heap- oder Stack-Objekte hat.

    Und wenn man es nicht weiss, gibt es keinen zuverlässigen Weg, es herauszufinden. Wenn die Rekonstruktion schwierig ist, muss man halt darauf achten, dass man zusätzlich irgendwo Information darüber abspeichert, ob Heap oder Stack als Speicherplatz dient.

    Aber eigentlich vollkommen unnötig, da man es wie gesagt wissen sollte - andernfalls hat man mit hoher Wahrscheinlichkeit etwas falsch gemacht...

    Bronson schrieb:

    wie soll man da flexibel sein?

    Entweder Konsistenz hineinbringen oder halt eine bool -Variable verwenden, wobei Letzeres weder schön ist noch von gutem Stil zeugt.


  • Administrator

    Wäre interessant zu wissen, was dein genaues Problem ist, dann könnte man dir Alternativen Vorschlagen? Vielleicht Funktionsüberladung?

    foo(int* p)
    {
      // ...
    }
    
    foo(std::auto_ptr<int> p)
    {
      foo(p.get());
    }
    
    int main()
    {
      int x;
      foo(&x);
    
      std::auto_ptr<int> p(new int(3));
      foo(p);
    
      return 0;
    }
    

    *Grad noch die Vorschau gesehen hat*
    Doch eine Zuweisung geht, man muss sie nur explicit angeben:

    intPtr = std::auto_ptr<int>(new int(3));
    

    Grüssli



  • @Dravere
    Ich meinte die Zuweisung aber umgekehrt.

    Ach, ich poste mal den eigentlichen Code:

    void OutputTime(SYSTEMTIME* time = 0)
    {
    	if(!time)
    	{
    		time = new SYSTEMTIME();
    		GetLocalTime(time);
    	}
    
    	// Wer löscht?
    
    	cout << time->wHour;
    }
    
    int main()
    {	
    	OutputTime(); // Soll aktuelle Zeit zeigen
    
    	SYSTEMTIME customTime = { 0, 0, 0, 0, 4 };
    	OutputTime(&customTime); // Soll eigene Zeit zeigen
    }
    


  • Ich sagte ja, du solltest dir das speichern. Liest du meine Beiträge eigentlich auch? 🙄

    void OutputTime(SYSTEMTIME* time = 0)
    {
        bool OnHeap;
        if(!time)
        {
            time = new SYSTEMTIME();
            GetLocalTime(time);
            OnHeap = true;
        }
        else
        {
            OnHeap = false;
        }
    
        if (OnHeap)
        {
            delete time;
        }
    
        cout << time->wHour;
    }
    

    Wahrscheinlich gibt es von Grund auf sauberere Lösungen, aber das kann ich wegen zu wenig Kontext nicht genau sagen.



  • Tja, genau das hatte ich von Anfang an... eine bool Variable.
    Wollte eben versuchen es doch "schöner" zu machen.



  • Ich würde das, wie Dravere gesagt hat, mit Überladung lösen:

    void OutputTime()
    {
        SYSTEMTIME time;
        GetLocalTime(&time); 
        cout << time.wHour; 
    }
    
    void OutputTime(const SYSTEMTIME &time)
    {
        cout << time.wHour; 
    }
    
    int main()
    {	
    	OutputTime(); // zeigt aktuelle Zeit an
    
    	SYSTEMTIME customTime = { 0, 0, 0, 0, 4 };
    	OutputTime(customTime); // zeigt eigene Zeit an
    }
    


  • Da wäre, wie von Dravere bereits angetönt, Überladung etwas. Du definierst zwei Funktionen, wovon eine keine Parameter und die andere einen vom Typ SYSTEMTIME* hat.



  • Ja, okay. Dachte es geht "schöner" (Ohne doppelten Code).
    Danke jedenfalls!



  • Bronson schrieb:

    Ja, okay. Dachte es geht "schöner" (Ohne doppelten Code).

    Du hast keinen doppelten Code. Falls innerhalb der beiden Funktionen das Gleiche gemacht wird (unabhängig von Speicherverwaltung), kannst du ja eine dritte Funktion definieren, die von beiden anderen aufgerufen wird.



  • Okay drei Funktionen, statt einer.
    Naja was solls...



  • Bronson schrieb:

    Okay drei Funktionen, statt einer.

    Was stört dich daran? Wenn man nicht weiss, ob ein Objekt auf dem Stack oder Heap erstellt wird, kann man das auch nicht in einer Zeile schnell richten. Zudem werden die Funktionen kaum gross sein.



  • Ja stimmt, die drei Funktionen nehmen nun etwa genauso viele Zeilen ein wie die eine Große zuvor.

    THX 👍


  • Administrator

    Wieso 3 Funktionen?
    Mit dem Beispiel von Tachyon:

    void OutputTime() 
    { 
        SYSTEMTIME time; 
        GetLocalTime(&time);
        OutputTime(time); // <- Hier kannst du die zweite Funktion aufrufen!
    } 
    
    void OutputTime(const SYSTEMTIME &time) 
    { 
        cout << time.wHour; 
    } 
    
    int main() 
    {    
        OutputTime(); // zeigt aktuelle Zeit an 
    
        SYSTEMTIME customTime = { 0, 0, 0, 0, 4 }; 
        OutputTime(customTime); // zeigt eigene Zeit an 
    }
    

    Grüssli



  • Bronson schrieb:

    Mist, dacht ich mir!
    Eine Zuweisung geht auch nicht, wie soll man da flexibel sein?

    int main()
    {	
    	int x = 7;
    
    	// Pointer könnte 0 sein, oder aber auf ein Stackobjekt zeigen
    	// int* intPtr = &x;
    	int* intPtr = 0;
    
    	std::auto_ptr<int> autoPtr;
    
    	if(!intPtr)
    	{
    		intPtr = new int(3);
    		//autoPtr = intPtr; // Geht ja nicht...
    	}
    
    	// In jedem Fall soll hier ein Objekt dahinterstecken und dann automatisch gelöscht werden
    	cout << *intPtr;
    }
    

    Wenn intPtr 0 ist, wird ein neues Heapobjekt erstellt, ansonsten zeigt intPtr schon auf ein Objekt, aber am Stack!

    Klar geht eine Zuweisung, du musst nur richtig zuweisen:

    int* intPtr = 0;
    
    	std::auto_ptr<int> autoPtr;
    
    	if(!intPtr)
    	{
    		intPtr = new int(3);
    		autoPtr = std::auto_ptr<int>(intPtr); // geht wohl
    	}
    


  • @Dravere
    Oh stimmt, viel eleganter.

    @hustbaer
    Oh, also wäre mein eigentliches Vorhaben mit dem auto_ptr eigentlich kein Problem gewesen (Wenn per new angelegt wird, bekommt der auto_ptr das Objekt auch zugewiesen und löscht somit dann ja automatisch...)

    Naja nun hab ich halt die Funktion überladen.

    Danke nochmals an alle!


Anmelden zum Antworten