Anzeige:
Ergebnis 1 bis 8 von 8

Thema: Hilfe beim Quellcode aufräumen

  1. #1
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177

    Hilfe beim Quellcode aufräumen

    Hi,

    ich versuche gerade meinen Quellcode auszumisten und bin dabei auf ein paar Fragen gestoßen, auf die ich bis jetzt noch keine so richtige Antwort gefunden habe.

    Code:
    void xyt(int *i; Object *obj);
    Klar kann man Variablen auch mit *i ansprechen, doch ist das auch
    ein schöner Stil?
    Zeiger Objekte, die man via PassByValue übergeben möchte, werden
    mit xyz(new Object(1,"a")); erzeugt. Doch müsste ich sie nicht eigentlich
    auch mit delete wieder löschen?

    Hoffe meine Fragen sind nicht zu Komisch und Ihr könnt mir helfen.
    Danke!

  2. #2
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Pointer auf int ist in C++ sehr ungewöhnlich. Sowas hat eigentlich nur dann Sinn, wenn man einen optionalen Ausgabeparameter braucht, also wo in der Funktionsdeklaration ein Defaultwert angegeben wird.

    Code:
    double parseDouble( string s, bool *ok = 0 );
    D.h. der Aufrufer kann (muss aber nicht) einen Pointer auf (in diesem Fall) bool übergeben und die Funktion benutzt den dann, um mitzuteilen, ob der String tatsächlich einen int enthielt.

    Bei einem normalen Ausgabeparameter nimmt man üblicherweise stattdessen eine Reference
    Code:
    void foo( int &i, Object *obj );
    Zur Frage bezüglich new/delete: ja, ein mit new erzeugtes Objekt muss wieder mit delete frei gegeben werden.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  3. #3
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177
    Stimmt schon das mit der Referenz &i, doch z.B. im Buch "c++ von A bis Z" Kap. 2.6.2 "Call by reference", wird z.B. auch mit *a=0;*b=0; gearbeitet. Deshalb warich mir nicht ganz sicher ob man es auch verwenden sollte.
    Gehen tut es ja ohne Probleme nach der ersten Zuweisung mit i= &j; Doch werde ich es wohl lieber nicht verwenden.

    Bei dem Objekt, ist für mich noch die Frage, wenn ich es aber als Wert übergeben möchte z.B.: an addWidget(QWidget*), wie mache ich es dann richtig?

  4. #4
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Zitat Zitat von dml Beitrag anzeigen
    Stimmt schon das mit der Referenz &i, doch z.B. im Buch "c++ von A bis Z" Kap. 2.6.2 "Call by reference", wird z.B. auch mit *a=0;*b=0; gearbeitet.
    Manche C++ Bücher sind da eigenartig, hab schon öfter welche gesehen, die char* als Strings anstatt std::string benutzen.

    Wie gesagt würde ich einen Ausgabeparameter nur dann als Pointer ausführen, wenn der Parameter optional sein muss.
    Eine Referenz sieht in der Funktion wie eine normale Variable aus, benötigt keine explizite Dereferenzierung, etc.

    Bei dem Objekt, ist für mich noch die Frage, wenn ich es aber als Wert übergeben möchte z.B.: an addWidget(QWidget*), wie mache ich es dann richtig?
    Das hängt davon ab, was mit dem Objekt gemacht wird.
    In diesem Fall wird das übergeben Widget vermutlich in einem Container gespeichtert und für einen polymorhpen Typ wie QWidget geht das einfach nur mittels Pointer.

    Ich denke als Faustregel kann man sagen: als Referenz wenn der Parameter nur in dieser Funktion verwendet wird, als Pointer wenn er für spätere Verwendung irgendwo zwischengespeichert wird.

    Ausnahme für die erste Regel eben die Eingangs erwähnten optionalen Ausgabearameter, für die zweite Regel Objekte die ohne Fehler kopiert werden können (z.B. std::string, QString und ähnliches, sogenannte "value-like objects").

    Wenn du dir bei bestimmten Fällen nicht sicher bist, können wir die ja konkret betrachten.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  5. #5
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177
    Hi!

    Erst einmal vielen herzlichen Dank für Dein Angebot. Ihr seid mal wieder viel zu freundlich zu mir! Doch um ehrlich zu sein, habe ich inzwischen mehrere andere Probleme (z.B. 2 dim. vector in class initialisieren, ...) bekommen um die ich mich jetzt leider vorher leider kümmern muss.

    Best Grüße!
    dml

  6. #6
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177
    Hi!

    Habe es endlich geschafft mein Projekt soweit wieder hin zu bekommen inkl. es zu erneuern. Link zu Programm (Dann tar.gz auswählen)
    Doch eigentlich möchte ich Euch nicht die Mühe auferlegen Euch das alles anzuschauen. Der Aufwand wäre dafür einfach zu groß. Wenn ja kleine Änderung bei Qt-Programm; PassBy-Funktionen jetzt wie bei CPP-Programm.

    Eine Sicherheitsfrage hätte ich aber noch. Gerade bei Parameterübergabe wie:
    Code:
    addWidget(QWidget*);
    Ist es ja auch möglich sie mit new
    Code:
    addWidget( new Widget);
    zu übergeben. Das müsste deshalb funktionieren, da Qt die Objekte selbt wieder löscht. Doch habe ich es auch schon gesehen bei:
    Code:
    add(Klasse * kl){
        kl_list.push_back(kl);
    }
    
    add(new Klasse);
    Das Funktioniert deshalb weil der vector sich jetzt um das Objekt kümmert.
    Ansonnsten würde es aber nicht funktionieren.
    Oder vielleicht besser ausgedrückt, auch bei der Parameterübergabe muss ich, wenn das Objekt mit new initialisiert wurde, kontrollieren, das es auch wieder mit delete gelöscht wird.


    Und danke für Eure vielen Bemühungen bei meinen vielen Fragen!
    Ansonsten würde mich natürliche eine so qualifizierte Kritik wie von Euch zu meinen Projekten natürlich interessieren. Aber wie gesagt den Aufwand dafür möchte ich Euch nicht auferlegen.
    Geändert von dml (12-01-2012 um 11:50 Uhr) Grund: Rechtschreibung + Grammatik

  7. #7
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Generell muss man bei der Benutzung von Zeigern immer klären, wo das entsprechende Objekt wieder gelöscht wird.

    Bei der Übergabe an oder aus Funktionen wird das dann üblicherweise dokumentiert, z.B. "Ownership stays with caller", also der Aufrufer bleibt Besitzer des Zeigers und ist damit für seine Löschung verantwortlich.

    Bei QObject kann das durchaus auch der Fall sein, ein QObject wird nur dann "automatisch" gelöscht, wenn es einen Parent hat und der gelöscht wird.

    In deinem Bespiel mit dem Vector ist ohne weiteren Code nicht sicher gestellt, dass Objekte des Typs Klasse auch wieder gelöscht werden.
    Das Lebensende des Vectors gibt nur seinen Speicher frei, nicht die Zeiger die du dran gespeichert hast.

    Generell empfiehlt es sich bei dieser Thematik sich in die Benutzung von Smart Pointer Typen einzulesen, z.B. shared_ptr aus boost oder QSharedPointer von Qt.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  8. #8
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177

    Naja, vielleicht doch ;)

    Um noch einmal auf Euer nettes Angebot zurück zu kommen, würde ich wenn Ihr Lust dazu habt, doch ein wenig Eure Hilfe in Anspruch nehmen.
    Ich überlege zur Zeit, meine beiden Programme Pointer und Parameterliste zusammen zu legen. Einzeln könnte ich zwar Themen wie **int und void* noch mit darin aufnehmen, doch befinde ich mich dabei auch schon am Ende des Programm-Gerüstes. Wenn ich die Programme aber zusammen legen kann ich unbeirrt auch Themengebiete wie z.B struct, OOP und was mir sonst so in Zukunft noch einfällt, mit aufnehmen.

    Doch erfüllt das Programm auch seine Aufgabenstellung, so das der Aufwand gerechtfertigt wäre? Also, ob es Anderen auch etwas bringt? Oder würde es mir nur eine Menge Aufwand verursachen, denn dann könnte ich mich auch für mich ergiebigeren Themen widmen.
    Geändert von dml (21-02-2012 um 11:26 Uhr)

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •