Ersatz für this innerhalb einer Klasse



  • versuch doch mal mit:

    TNMHTTP *HTTPAccess = new TNMHTTP(NULL);
    


  • BlutigerAnfänger schrieb:

    TNMHTTP *HTTPAccess = new TNMHTTP(this);
    HTTPAccess->InputFileMode = false;
    HTTPAccess->TimeOut = 25000;
    HTTPAccess->Get("www.heise.de");
    AnsiString Muell = HTTPAccess->Body;
    

    funktioniert perfekt außerhalb einer Klasse...

    Du musst im irgendetwas vorsetzen, was von TComponent abgeleitet ist. "Außerhalb einer Klasse" funktioniert der obere Code, weil this unter Garantie eine Form ist (welche von TComponent abgeleitet und übrigens auch ne Klasse ist *g*). Im Zweifelsfall nimmst du einfach Application.

    TNMHTTP *HTTPAccess = new TNMHTTP(Application);
    


  • Supi, funktioniert mit NULL und Application, danke.
    Ist eigentlich beides gleichwertig? Und wozu ist der Murks überhaupt gut?
    TNMHTTP scheint irgendwie mit typedef zusammenzuhängen. Zumindest bekomme ich folgende Fehlermelung:

    Ungültige Verwendung von typedef 'TNMHTTP'

    bei

    TNMHTTP *HTTPAccess = new TNMHTTP(TNMHTTP);
    


  • F98 schrieb:

    delete HTTPAccess
    

    Ist das bei NULL oder Application notwendig? Dabei stürzt mir auch das Programm ab. Sorry, dass ich noch so ahnungslos bin.



  • Mit dem Abstürzen nehme ich zurück. Allerdings bei delete im Destructor gibt es einen Absturz (ist aber nicht so schlimm, da delete sinnvollerweise doch woanders steht).

    Ich möchte aber immer noch wissen ob das mit NULL oder Application saubere Programmierung ist? Falls nein, wie sollte ich es anders machen?



  • BlutigerAnfänger schrieb:

    Mit dem Abstürzen nehme ich zurück. Allerdings bei delete im Destructor gibt es einen Absturz (ist aber nicht so schlimm, da delete sinnvollerweise doch woanders steht).

    Warum sollte es auch funktionieren, schließlich ist HTTPAccess nur im Kunstruktor deklariert / definiert. Das delete ist dazu da, das der Speicherplatz wieder freigegeben wird, den HTTPAccess belegt hat. Würde man kein delete einsetzen, würde HTTPAccess noch da aber kann nicht mehr angesprochen werden. Und NULL ist eben nicht das Gleiche wie Application. NULL zu übergeben ist ein schlechter Stil. Nimm lieber Application.

    @F98: Es ist eben kein Schwachsinn, ich glaube du solltest dir auch mal ansehen, was alles für Parameter bergeben werden können. Es kann eben nicht nur TComponent* übergeben werden, sondern sinnvoller Weise auch &TNMTHTTP.



  • Windoof schrieb:

    Warum sollte es auch funktionieren, schließlich ist HTTPAccess nur im Kunstruktor deklariert / definiert.

    Sorry, ich sehe jetzt, da ist mir ein ein Fehler unterlaufen. Ich hab HTTPAccess einmal als Privat deklariert und dann noch mal im Konstruktor (statt nur new im Konstruktor), das mußte natürlich schief gehen.



  • @Windoof

    TNMTHTTP auf die Art und Weise zu initialisieren funktioniert nur deswegen weil dessen Zeiger kurz vor dem new noch NULL ist. Somit übergibst Du indirekt NULL im Konstruktor.

    Schade das es hier keinen :sniper gibt :p



  • F98 schrieb:

    TNMTHTTP auf die Art und Weise zu initialisieren funktioniert nur deswegen weil dessen Zeiger kurz vor dem new noch NULL ist. Somit übergibst Du indirekt NULL im Konstruktor.

    Ein Unterschied muß da aber schon bestehen, bei Windoofs Vorschlag gibt es einen Absturz, NULL funktioniert.



  • F98 schrieb:

    TNMTHTTP auf die Art und Weise zu initialisieren funktioniert nur deswegen weil dessen Zeiger kurz vor dem new noch NULL ist.

    Das es NULL ist, würde ich nicht 100% behaupten. Das ist ein nicht initializierter Zeiger, der auf alles mögliches zeigen kann.

    Deshalb auch Abstürze.

    F98 schrieb:

    Schade das es hier keinen :sniper gibt :p

    😃



  • F98 schrieb:

    Schade das es hier keinen :sniper gibt :p

    Es sind eben nicht alle solche Superzocker wie du. Und was diesen Zeiger angeht: Es ist eine Referenz, die übergeben wird, aber das ist auch egal, jedenfalls ist diese Referenz dazu da, dass der Konstruktor etwas damit anfangen kann, anstatt mit NULL. bei NULL weiß der compiler nicht, welche Methode du aufrufen willst, wilölst du die haben, woe TComponent* übergeben kannst oder den anderen? - Deshalb lieber die Referenz als NULL, aber am Besten ist natürlich Application zu übergeben.



  • Windoof schrieb:

    F98 schrieb:

    Schade das es hier keinen :sniper gibt :p

    Es sind eben nicht alle solche Superzocker wie du. Und was diesen Zeiger angeht: Es ist eine Referenz, die übergeben wird, aber das ist auch egal, jedenfalls ist diese Referenz dazu da, dass der Konstruktor etwas damit anfangen kann, anstatt mit NULL. bei NULL weiß der compiler nicht, welche Methode du aufrufen willst, wilölst du die haben, woe TComponent* übergeben kannst oder den anderen? - Deshalb lieber die Referenz als NULL, aber am Besten ist natürlich Application zu übergeben.

    was erzällst du da für ein schwachsinn?!

    auf NULL kann man immer prüfen und dem zu folge handeln.

    bei deinem auf irgendwohinkeineahnung zeigenden Zeiger versucht Compiler irgendwelche daten, die der "Parameter-Klasse" angeblich entsprechen, zu entlocken, was zu einer AccessVioletion führt, weil an der Stelle, wohin der Zeiger zeigt, gar keine "richtigen" Daten existieren.



  • BlutigerAnfänger schrieb:

    Supi, funktioniert mit NULL und Application, danke.
    Ist eigentlich beides gleichwertig? Und wozu ist der Murks überhaupt gut?

    Alles, was man mit new erzeugt, muss auch mit delete wieder zerstört werden, soweit nix Neues. TComponent und alle davon abgeleiteten Klassen (wie TNMHTTP) vereinfachen diesen Prozess. Bei new übergibt man einen sog. Owner. Das so erzeugte Objekt wird automatisch zerstört, wenn der Owner zerstört wird d.h. man spart sich das delete oder auf das Beispiel bezogen: Wird das Programm beendet (Application wird zerstört), so verschwindet auch das Objekt vom Typ TNMHTTP aus dem Speicher.

    Wird NULL anstelle von Application übergeben, fällt besagter Mechanismus natürlich weg. In dem konkreten Falle sollte man aber eh nicht auf das Löschen mit delete verzichten; oder aber man setzt noch einen drauf und leitet cWebpage auch von TComponent ab.

    class cWebpage : public TComponent
    {
       TNMHTTP * FHTTPAccess;
    
    public:
       __fastcall cWebpage(TComponent *Owner, AnsiString Link);
       ...
    };
    
    __fastcall cWebpage::cWebPage(TComponent *Owner, AnsiString Link)
       : TComponent(Owner)
    {   FHTTPAccess = new TNMHTTP(this); // jetzt funktioniert this, da unsere Klasse ja von TComponent abgeleitet ist
        ...
    }
    

    Vorteil A: FHTTPAccess wird automatisch zerstört, ohne das wir uns darum kümmern müssen.
    Vorteil B: Erzeugen wir ein cWebpage-Objekt und übergeben ihm als Owner einen Zeiger auf eine Form o.ä., dann wird unser cWebpage-Objekt ebenfalls zerstört, wenn die Form geschlossen wird.
    Nachteil: ein cWebpage-Objekt kann nur noch mit new erzeugt werden; ein einfaches

    cWebpage page;
    

    funktioniert nicht mehr.



  • Vielen Dank Killing me softly, zweimal eine super Erklärung. Da lernt man richtig was dazu!



  • Also eigentlich wollte ich diesen Thread ja an mir vorübergehen lassen, aber ...

    Windoof schrieb:

    NULL zu übergeben ist ein schlechter Stil. Nimm lieber Application.

    Häää?! Wie kommst Du denn darauf?? Wenn Du NULL übergibst, bist Du lediglich selbst für die Vernichtung der Instanz verantwortlich. Das hat überhaupt nichts mit schlechtem Stil zu tun. Wenn jemand NULL übergibt, lebt er entweder gefährlich oder weiß genau, was er tut.

    F98 schrieb:

    TNMTHTTP auf die Art und Weise zu initialisieren funktioniert nur deswegen weil dessen Zeiger kurz vor dem new noch NULL ist.

    Pointer werden prinzipiell nicht automatisch mit NULL initialisiert. Daß so etwas hier funktioniert:

    TMyClass* myObject = new TMyClass(myObject);
    

    erstaunt mich also eher. Das würde i.allg. nur dann zu keiner AV führen, wenn der Konstruktor den übergebenen Zeiger prüft und gegebenenfalls automatisch den Owner auf NULL setzt.



  • @Xqgene & dschensky

    Ihr habt natürlich recht, das nicht in jedem Fall der Zeiger mit NULL initialisiert wird.


Anmelden zum Antworten