Stilfrage



  • Gartenzwerg: Ist dein Kumpel zufällig Pascalprogrammierer?



  • hi,
    er macht Informatikunterricht in der Schule. Die habe das Schuljahr mit Turbo Pascal begonnen und sind jetzt bei C++. C++ soll auch noch im nächsten Jahr weitergehen.

    Also macht es in den meisten Fällen kein Sinn, eine init()- und destroy()-Funktion in die Klasse mit einzubauen?

    Tschau Gartenzwerg

    PS: Die Vorteile konnte er mir auch nicht nennen, er sagt da habe er gerade nicht aufgepasst, aber es ist 100%ig besser. Nun da ich noch nie etwas davon gehört hatte, wollte ich mal nachfragen ob er recht hat oder nicht.

    [ Dieser Beitrag wurde am 24.06.2003 um 06:22 Uhr von Gartenzwerg editiert. ]



  • Hör nicht auf Leute, die sagen: 100% isses so besser, frag mcih aber net wieso, weil ich eigentlich kein Plan hab.



  • Hör insbesondere nicht auf Leute, die einen Stil aus einer Sprache auf eine andere übertragen wollen. Konstruktoren und Destruktoren werden in Turbo Pascal nicht automatisch aufgerufen, was dazu führt, dass man immer folgende typische Sequenz wiederfindet:

    var foo: SomeClass;
    begin
      foo.Init;
      foo.DoSomething(bar);
      foo.Done
    end;
    

    Offensichtlich ist das in C++ nicht notwendig. Sinnvoll wär es auch nicht. Kannst dich ja mal bei C++ Gurus (Herb Sutter, Bjarne S., usw.) umgucken, wie die das handhaben 😉



  • hi,
    danke für die Hinweise!

    @dEUs: Den Rat werd ich mir zu Herzen nehmen.

    Tschau Gartenzwerg



  • Wenn man ein Logging benutzt kann man im dtor mittels einer Hilfsvariable
    entscheiden ob die Klasse schon beendet wurde und einen Vermerk ins Log
    schreiben. Ist aber nur ne Spielerei.

    Ein anderer Vorteil ist das man die Klasse auch mitten in einer Funktion
    beenden kann, um z.B. Rescourcen freizugeben. Ist aber nur was für Ungeduldige.
    Und man muss aufpassen, dass eine Rescource nicht 2x freigegeben wird.



  • Original erstellt von C Newbie:
    Ein anderer Vorteil ist das man die Klasse auch mitten in einer Funktion
    beenden kann, um z.B. Rescourcen freizugeben. Ist aber nur was für Ungeduldige.
    Und man muss aufpassen, dass eine Rescource nicht 2x freigegeben wird.

    meinst du

    code;
    code;
    {
      ifstream datei(foo);
      mah_was(datei);
    }
    code;
    

    geil, oder?

    ohne den ganzen quatsch mit detroy und init

    wenn man Ctor und Dtor schon hat, dann soll man auch die vorteile verwenden...

    Ich würd ja auch gern was zu deinem 'Logging'-Argument sagen, aber ich kapiers nicht.

    BTW: RAII rules!



  • Hab ja auch nie behauptet das man unbedingt Init/Exit Funktionen braucht.
    Wer sie braucht benutzt sie wer nicht der dann halt nicht.

    Zum Logging:

    class Wichtig
    {
     bool isEnded;
    
    public:
     Wichtig() {isEnded = false;}
     void Exit() {isEnded = true;}
     ~Wichtig() 
     {
       if(!isEnded)
       {
         log("Hast Wichtig nicht beendet böse");
         exit();
       }
     }
    
    };
    


  • Man kann damit also Fehler erkennen, die man ohne das nicht hätte? 😃



  • Genau. Wie gesagt ist nur ne Spielerei.



  • Original erstellt von C Newbie:
    Genau. Wie gesagt ist nur ne Spielerei.

    ne sinnlose

    sobald man status werte hat die anzeigen ob das objekt gültig ist oder nicht, sollte man nochmals darüber nachdenken (meistens ists n design fehler)



  • Ich werde diesen Rat in Zukunft berücksichtigen.

    Auch für sinnlose Spielereien 😉



  • Ist nicht immer eine sinnlose Spielerei. In STL Containern kann es sehr hilfreich sein, wenn man nicht über Pointer die Klassen hält. Sonst wird nach dem CopyCTor immer der DTor aufgerufen, und die Initialisierten sachen drin werden überschrieben usw.



  • Erklär ...

    Hört sich irgendwie schmutzig an was du vorhast, aber du klingst, als würdest du das ständig machen:)



  • klingt so abwegig, daß ich gar nicht abwarten muss, was er genau vor hat.



  • Original erstellt von SnorreDev:
    Ist nicht immer eine sinnlose Spielerei. In STL Containern kann es sehr hilfreich sein, wenn man nicht über Pointer die Klassen hält. Sonst wird nach dem CopyCTor immer der DTor aufgerufen, und die Initialisierten sachen drin werden überschrieben usw.

    😕 😕 😕



  • Ich halte es nicht für Mist, was ich da verzapft habe.

    #include <cstdlib>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <vector>
    
    class MyClass {
        char *ptr;
    
    public:
        MyClass( int size ) : ptr( NULL ) {
            std::cout << "Ctor" << std::endl;
            ptr = new char[size];
    
            for( char i = 0; i < size; i++ ) {
                ptr[i] = i+65;
            }
        }
    
        virtual ~MyClass() {
            std::cout << "DTor" << std::endl;
            delete [] ptr;
            ptr = NULL;
        }
    
        inline char* GetPtr() {
            return this->ptr;
        }
    };
    
    std::vector< MyClass > vec;
    
    int main()
    {
        vec.push_back( MyClass( 10 ) );
    
        char *ptr = vec.begin()->GetPtr();
    
        for( char i = 0; i < 10; i++ )
            std::cout << ptr[i] << " - ";
    
        int i;
        std::cin >> i;
    
        return EXIT_SUCCESS;
    }
    

    Klar - wenn ich vector genommen hätte statt PTR, dann würde es gehen, nur ist vector nicht immer die beste Wahl.
    Versteht ihr was ich meine? Und ich Packe z.b. keinen Vertexbuffer oder so in einen vector. Das währe ein viel zu großer Verwaltungsaufwand vom Speicher. Besonders beim Terrain, wo die Meshes echt riesig sind.



  • kapier net, was du meinst.



  • Cool, ein Smart Pointer ohne Smart. Vielleicht sollte man den Smartass-Pointer nennen *g*



  • @volkard:
    Ich meine z.B. bei meinem Terrain habe ich Tiles, die jedes einzelne ein Mesh enthalten. Ich kann so wie´s mir am liebsten ist aber nicht im DTor zerstöhren. Denn sonst sind die gespeicherten daten Hinüber. Also bleibt mir nur der weg über ein extra Release, Kill, Destroy oder wie man das auch immer nennt.

    Beim push_back wird der Copy constructor meiner Class aufgerufen, danach der Destruktor, da die eigentliche Instanz die ich erzeugt habe ja nicht weiter Existiert -> vec.push_back( MyClass( 10 ) );

    Wenn du den Code ausführst, dann wirst du sehen - er erstellt den Speicher, schreibt ABCDEF... rein, und löscht ihn durch den DTor. Danach kriegtst du durch die schleife nur müll ausgegeben.

    @Bashar:
    hehe - smartass pointer sind cool - ne jetzt ohne schmarn - kann sein, weil ich nicht der Held im OOP bin, und duch sehr lange Prozedurale Programmierung, daß das Design dann in meinem Terrain Kacke ist, nur weiß ichs nicht besser - aber das der DTor aufgerufen wird läßt sich leider nicht vermeiden!


Anmelden zum Antworten