Ersatz für this innerhalb einer Klasse



  • bei

    #include "NMHTTP.hpp"
    cWebpage::cWebpage(AnsiString Link)
        {
        TNMHTTP *HTTPAccess = new TNMHTTP(this);
        HTTPAccess->InputFileMode = false;
        HTTPAccess->TimeOut = 25000;
        HTTPAccess->Get(Link);
        ...
        }
    

    gibt es folgende Fehlermeldung:
    "Keine Übereinstimmung für 'TNMHTTP::TNMHTTP(cWebpage * const)' gefunden"

    Was muß ich statt "this" schreiben?



  • Dann schau doch einfach mal nach was

    TNMHTTP(...)
    

    als Parameter erwartet und dann vergleiche mal den Typ dieses Parametes mit dem Typ von this.

    Außerdem:

    delete HTTPAccess
    

    nicht vergessen!



  • BlutigerAnfänger schrieb:

    Was muß ich statt "this" schreiben?

    HTTPAccess.



  • Windoof schrieb:

    BlutigerAnfänger schrieb:

    Was muß ich statt "this" schreiben?

    HTTPAccess.

    wie das jetzt???

    HTTPAccess wird erst mit new erzeugt und du schlägst vor, dass die gleich an Ctor, der sie erstellt, übergeben wird. 😕 😕 😕



  • Genau. Kannst es ja ausprobieren, z.B. mit

    TEdit* eNew=new TEdit(eNew);
    

    Du wirst sehen, dass es klappt.



  • @WinSuperDoof:

    Na logo geht das, ist aber totaler Schwachsinn, denn dem Konstruktor sollte bestimmt ein Zeiger auf einen fremden Owner und nicht auf sich selbst übergeben werden.



  • 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.

    Wenn ich HTTPAccess innerhalb der Klasse für this einsetze, wird es zwar kompiliert, aber schmirt mir genau an dieser Stelle (TNMHTTP *HTTPAccess = new TNMHTTP(HTTPAccess)) ab:

    Im Projekt xxxx ist eine Exception der Klasse EAccessViolation aufgetreten. Meldung:
    'Zugriffsverletzung bei Adresse 00428846 in Modul 'xxxx'. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start
    fortsetzen.

    F98 schrieb:

    Dann schau doch einfach mal nach was

    TNMHTTP(...)
    

    als Parameter erwartet und dann vergleiche mal den Typ dieses Parametes mit dem Typ von this.

    Das ist eben mein Problem, ich finde es nicht raus.



  • 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.


Log in to reply