Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Funktionsaufrufe

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] > 2 < [ 3 ]
010
21.08.2003, 14:30 Uhr
Spacelord
Hoffnungsloser Fall



Zitat:
Loddab postete
Im Endeffekt werde ich die Leute fragen die die Klassen benutzen werden was ihnen besser gefällt. Warum sollte man deiner Meinung nach globale Funktionen und Funktionspointer vermeiden?


Im Grunde hast du Frage schon selber beantwortet.
....die Leute fragen die die Klassen benutzen werden ....
....globale Funktionen und Funktionspointer .....

Schlechte Wiederverwertbarkeit,schlechte Kapselung,schlechtes Geheimnisprinzip,schlechte Wartbarkeit...
Globale Funktionen treten die Grundprinzipien der OOP mit Füssen.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
011
21.08.2003, 14:56 Uhr
typecast
aka loddab
(Operator)


....die Leute fragen die die Klassen benutzen werden ....: Ich möchte ihnen aber wenigstens ein paar Anhaltspunkte geben können wo die Probleme liegen können. Und wenn virtual, 0xdeadbeef und jetzt auch du mir davon abraten, dann muss es einige davon geben.

Schlechte Wiederverwertbarkeit: Klar. Aber die Funktionen müssen eh in jedem Projekt neu geschrieben werden (wenn man sie immer brauchen würde, würde ichsie mit der Klasse ausliefern)

Schlechte Kapselung, schlechte Wartbarkeit: Könntest du das noch genauer erklären?
--
All parts should go together without forcing. ... By all means, do not use a hammer. (IBM maintenance manual, 1925)

Dieser Post wurde am 21.08.2003 um 14:56 Uhr von Loddab editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
012
21.08.2003, 15:30 Uhr
Spacelord
Hoffnungsloser Fall


Du möchtest Klassen ausliefern,aber irgendwelche Funktionen müssen trotzdem noch global deklariert werden?
Wo ist denn da die Kapselung,wenn die(anscheinend relevante) Funktionalität ausserhalb der Klasse liegt?
Eine "gute" Schnittstelle zeichnet sich dadurch aus dass ein Kundenprogramm ohne jegliche Änderung weiterarbeitet obwohl du die interne Implementierung deiner Klasse geändert hast.Davon kann in diesem Zusammenhang ja wohl keine Rede sein.
Ein Grundsatz der OOP ist das dem Kunden die Implementierung deiner Klasse völlig egal sein kann solange er die öffentliche Schnittstelle nutzen kann,und diese die erwarteten Ergebnisse liefert.
Wer sagt dir dass der Kunde die globale Funktion so auslegt dass sie mit deiner Implementierung korrekt zusammenarbeitet?Dafür müsste der Kunde schon wieder wissen wie deine Klasse Implementiert ist.
Ein ganz simples Beispiel,ganz unabhängig jetzt von dem realen Problem.Die globale Funktion liefert einen Zeiger auf irgendwas zurück.
Woher soll der Kunde wissen ob er den Zeiger in seiner Funktion auf NULL testen muss,oder ob das in deiner Klasse geprüft wird?
Oder die Funktion liefert einen int-Wert,der in irgendeiner Form,innerhalb der Klasse weiterverwendet wird.Muss der Kunde prüfen ob der Wert gültig ist,oder passiert das in der Klasse(z.B. eine Klasse die Kalenderwochen verarbeitet,Werte <1 und >53 für die Woche wären falsch,(angenommen)jetzt prüft weder die Kundenfunktion noch deine Klasse ob der gelieferte Wert innerhalb der Grenzen liegt so erscheint dann z.B. auf der Arbeitskarte im Betrieb ein Termin für die KW 179/2003).
Es ist einfach unschön wenn deine interne Implementierung Einfluss auf das benutzende Programm hat.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
013
21.08.2003, 15:41 Uhr
typecast
aka loddab
(Operator)


Die Implementierugn der Klasse ist hier für den Benutzer völig uninteressant. Die Funktion liefert auch nichts an die Klasse zurück und nimmt auch nichts aus der Klasse mit. Das einzige was der Benutzer der Klasse wissen muss, ist dass diese Funktion zu einem bestimmten Zeitpunkt ausgeführt wird. Sie hat im Grunde nur das mit der Klasse zu tun. Sonst nichts.
--
All parts should go together without forcing. ... By all means, do not use a hammer. (IBM maintenance manual, 1925)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
014
21.08.2003, 15:42 Uhr
virtual
Sexiest Bit alive
(Operator)


@loddab
Eine Alternative zu Deinem sagen wir mal sehr offenen Stil und virtuellen Methoden im Button selbst gibt es auch noch,
indem man die reine Abarbeitung von Events in eine separate Klasse legt:


C++:
class ActionHandler;

class Button
{
private:
    ActionHandler* handler;

public:
    void setHandler(ActionHandleri* handler) { this->handler = handler; }
    void handleAction() { if (NULL!=handler) handler->handle(); }
};


class ActionHandler
{
    Button* button;

public:
    ActionHandler(Button* button) { this->button = button; button->setHandler(this); }

    virtual void handle() { /* Das machen, was der Button machen soll */ }
};



Das Framework würde nun handleAction vom Button aufrufen, welches wiederrum die handle Methode des ActionHandlers aufruft.
Und dort könntest Du dann deine Aktion implementieren. Mag vielleicht auf den ersten Blick wenig Sinnvoll erscheinen, hat aber gegenüber einer einfachen Version mit einer virtuellen Routine in Button klare Vorteile:
Wenn man sich vorstellt, daß man nicht nur eine Klasse Button hat, sondern eben solche Klasse wie RedButton, SuperBingoButton usw. die alle von Button ableitet sind (und ggf nur visuell unterschiedlich erscheinen), so kann man seine Eventabarbeitung unabhängig davon implementieren, welche Art von Button der User grade präsentiert bekommt.

Bearbeitung:

Anwendung:

C++:
Button btn;
CloseAction cls(&btn); /* CloseAction is derived von Actionhandler */




--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 21.08.2003 um 15:44 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
015
21.08.2003, 15:54 Uhr
0xdeadbeef
Gott
(Operator)


Um nochmal auf die Fragen einzugehen - Mit dieser Funktionspointer-Geschichte läufst du in Gefahr, Code aufzurufen, wo keiner ist. Nimm folgendes Beispiel (Objekt sei definiert wie in virtuals Beispiel):

C++:
Objekt instanz;
instanz.funkt(); //<-- Hoppla, da ist ja noch gar keine Funktion zugewiesen


Das ist etwas, was du mit virtuellen Methoden nicht hast. Oder stell dir eine Situation vor, in der es für eine Funktion nur sinnvoll ist, eine ganz bestimmte Funktion zu benutzen. Bei deinem Ansatz hast du keine Möglichkeit, dass nachzuprüfen, mit virtuellen Funktionen nimmst du einfach direkt die abgeleitete Klasse an. Oder stell dir vor, du willst this in der Funktion verwenden. Mit virtuellen Methoden kein Problem, bei deinem Ansatz musst du dich darauf verlassen, dass der Programmierer begreift, dass er gerade mit etwas völlig C++-atypischem arbeitet und das Objekt sich selbst übergibt. Solcher Code:

C++:
instanz.do_something(&instanz, param1, param2);


sollte eigentlich der Vergangenheit angehören. Es gibt tausende von Beispielen wie diese. Und wenn du tatsächlich mal Funktionen eines Objektes zur Laufzeit austauschen musst, dann nimm wenigstens Funktoren dafür.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 21.08.2003 um 15:55 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
016
21.08.2003, 16:06 Uhr
typecast
aka loddab
(Operator)


Ok danke für die Tipps. Ihr habt mich überzeugt.
--
All parts should go together without forcing. ... By all means, do not use a hammer. (IBM maintenance manual, 1925)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
017
21.08.2003, 16:08 Uhr
Spacelord
Hoffnungsloser Fall


@Loddab:
Die Funktion soll aber nunmal irgendwas machen was für das Programm wichtig ist(sonst bräuchte man sie nicht)!
Und weiter ist Fakt dass deine Funktion in irgend einer Weise den Zustand deines Objekts verändert,sonst bräuchtest du keinen Funktionszeiger als Attribut.
Meine Beispiele waren eher theoretischer Natur und meine ganze Argumentation ist rein theoretisch(das reale Problem ist für mich gerade mal völlig egal,und es ist mir auch egal ob die Funktion irgendwas zurückliefert oder nicht.Hier geht es gerade ums Prinzip.).
Tatsache ist dass das hier ein klassisches Beispiel dafür ist das man mit einer OOP-Sprache nicht zwangsläufig objektorientiert programmiert.
Wenn dich die Prinzipien der OOP nicht interessieren,warum programmierst du dann nicht gleich mit C?
Mit einer prozeduralen Sprache kommt man im allgemeinen wesentlich schneller zum (ersten) Ziel,was danach kommt kann allerdings schlimmstenfalls zum Neuentwurf führen.
Seit etwa 30 Jahren machen sich schlaue Köpfe Gedanken darüber warum es sich lohnt beim ersten Entwurf vielleicht etwas mehr Zeit zu investieren,um später eine bessere Basis zu haben und ich hab keine Lust mit dir darüber zu diskutieren ob diese Überlegungen jetzt auf deinen speziellen Ansatz passen oder nicht.

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
018
21.08.2003, 16:18 Uhr
0xdeadbeef
Gott
(Operator)


Da war wohl einer zu langsam, was?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
019
21.08.2003, 16:26 Uhr
Spacelord
Hoffnungsloser Fall


Yep

MfG Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] > 2 < [ 3 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: