Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: Allgemeines zum Magazin ::  Klassen ohne getter/setter?     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
Artchi
Autor

Benutzerprofil
Anmeldungsdatum: 16.03.2002
Beiträge: 8576
Beitrag Artchi Autor 18:37:21 16.03.2008   Titel:   Klassen ohne getter/setter?            Zitieren

Also mich würde mal ein Artikel freuen, wie man denn Klassen-Designs ohne Getter und Setter hinbekommen soll. Lese hier immer wieder im Forum, das manche Leute es ein schlechtes Design finden. Aber mich würde mal interessieren, wie das ganze denn real umgesetzt werden sollte?

Wie würde man z.B. sowas "besser" lösen können:
C/C++ Code:
class Widget
{
    public:
       void setModel(Model);
       Model getModel();
};
C/C++ Code:
class Widget
{
public:
void setModel(Model);
Model getModel();
};
C/C++ Code:
class Widget
{
    public:
       void setModel(Model);
       Model getModel();
};

_________________
Bring back the Windows Start Menu Petition | GoPetition


Zuletzt bearbeitet von Artchi am 18:39:39 16.03.2008, insgesamt 1-mal bearbeitet
Keks9
Unregistrierter




Beitrag Keks9 Unregistrierter 19:02:20 16.03.2008   Titel:              Zitieren

Ich würde den Artikel schreiben.
scrub
Mitglied

Benutzerprofil
Anmeldungsdatum: 17.09.2004
Beiträge: 3500
Beitrag scrub Mitglied 20:08:14 16.03.2008   Titel:   Re: Klassen ohne getter/setter?            Zitieren

Anmerkung: Das ist nicht meine Meinung, sondern eine Argumentation, mit der ich tatsächlich konfrontiert wurde.

C/C++ Code:
class Widget
{
    public:
        Model model;
};
C/C++ Code:
class Widget
{
public:
Model model;
};
C/C++ Code:
class Widget
{
    public:
        Model model;
};


Begründung:

Der Setter kann nur wie folgt implementiert sein...
C/C++ Code:
Widget::setModel(Model m)
{
    model = m;
}
C/C++ Code:
Widget::setModel(Model m)
{
model = m;
}
C/C++ Code:
Widget::setModel(Model m)
{
    model = m;
}

... weil das "die Definition" eines Setters ist. Der darf nicht anders aussehen. Also kann man den Member gleich public machen (siehe oben).

_________________
"Ich gehöre nicht zu denen, die die Bundesrepublik ruinieren wollen. Ich hoffe, Sie machen noch Halt, Herr Kohl, ehe Sie unwissentlich vieles dazu tun, daß sie ruiniert wird!"


Zuletzt bearbeitet von scrub am 20:10:10 16.03.2008, insgesamt 1-mal bearbeitet
ich_du_er
Unregistrierter




Beitrag ich_du_er Unregistrierter 20:15:26 16.03.2008   Titel:              Zitieren

Wie wäre es mit einem
C/C++ Code:
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
class Widget
{
public:
    void model(const Model&);
    const Model& model() const;

private:
    Model model_;
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
class Widget
{
public:
void model(const Model&);
const Model& model() const;

private:
Model model_;
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
class Widget
{
public:
    void model(const Model&);
    const Model& model() const;

private:
    Model model_;
};
Dann kann man bei Bedarf z.B. die beiden Funktionen duch einen public Funktor ersetzen, sodass keine änderungen im Clientcode mehr erfolgen müssen:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Widget
{
public:
    ModelImpl model;

private:
    class ModelImpl
    {
    public:
        void operator(const Model&);
        const Model& operator() const;

    private:
        Model model_;
    };
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Widget
{
public:
ModelImpl model;

private:
class ModelImpl
{
public:
void operator(const Model&);
const Model& operator() const;

private:
Model model_;
};
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Widget
{
public:
    ModelImpl model;

private:
    class ModelImpl
    {
    public:
        void operator(const Model&);
        const Model& operator() const;

    private:
        Model model_;
    };
};
Badestrand
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2006
Beiträge: 4342
Beitrag Badestrand Mitglied 20:16:35 16.03.2008   Titel:              Zitieren

Ich fände so einen Artikel auch interessant! Wie sollte er denn aufgemacht sein? Generelles Klassen-Design vor dem eigentlich Programmieren (also Planung) mit Fallbeispielen oder wie?
Und komplett ohne Getter? Weil einige Daten muss man ja rausholen?


Zuletzt bearbeitet von Badestrand am 20:18:06 16.03.2008, insgesamt 1-mal bearbeitet
Apollon
Mitglied

Benutzerprofil
Anmeldungsdatum: 22.04.2003
Beiträge: 1879
Beitrag Apollon Mitglied 20:20:55 16.03.2008   Titel:              Zitieren

Badestrand schrieb:
Und komplett ohne Getter? Weil einige Daten muss man ja rausholen?

Warum muss man das? Warum nicht einfach das Objekt, das die noetigen Daten bereithaelt, uebergeben?

_________________
"Stil ist ein richtiges Weglassen des Unwesentlichen." - Anselm Feuerbach
scrub
Mitglied

Benutzerprofil
Anmeldungsdatum: 17.09.2004
Beiträge: 3500
Beitrag scrub Mitglied 20:30:59 16.03.2008   Titel:              Zitieren

Weil es Inkonsistenz zur Folge haben könnte.

_________________
"Ich gehöre nicht zu denen, die die Bundesrepublik ruinieren wollen. Ich hoffe, Sie machen noch Halt, Herr Kohl, ehe Sie unwissentlich vieles dazu tun, daß sie ruiniert wird!"
Badestrand
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2006
Beiträge: 4342
Beitrag Badestrand Mitglied 20:33:00 16.03.2008   Titel:              Zitieren

Apollon schrieb:
Badestrand schrieb:
Und komplett ohne Getter? Weil einige Daten muss man ja rausholen?

Warum muss man das? Warum nicht einfach das Objekt, das die noetigen Daten bereithaelt, uebergeben?

Ach stimmt, irgendwie meinte ich das auch gar nicht so :-/ Meine Gedanken waren eben wie folgt: Die Methode "size()" in std::string sei ja auch ein Getter, weil es die Länge zurückgibt.
Knuddlbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.12.2001
Beiträge: 5237
Beitrag Knuddlbaer Mitglied 20:33:26 16.03.2008   Titel:              Zitieren

und wie kommt man an die nötigen Daten rann ?
Badestrand
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2006
Beiträge: 4342
Beitrag Badestrand Mitglied 20:44:32 16.03.2008   Titel:              Zitieren

Knuddlbaer schrieb:
und wie kommt man an die nötigen Daten rann ?
Jedenfalls nicht, indem man eine Referenz auf ein Klassenobjekt zurückgibt. Eher halt die nur wirklich nötigen Daten als Datensatz rausgeben. Mit Referenz ist die Klasse z.B. gezwungen, selbst ein Objekt dieser Art zu halten. Bei der Methode "size" von std::string können die Daten ja auch berechnet werden, es ist halt entkoppelter. So sehe ich das jedenfalls.
Apollon
Mitglied

Benutzerprofil
Anmeldungsdatum: 22.04.2003
Beiträge: 1879
Beitrag Apollon Mitglied 20:46:38 16.03.2008   Titel:              Zitieren

Knuddlbaer schrieb:
und wie kommt man an die nötigen Daten rann ?

Hoe? Man hat doch freien Zugriff drauf... Ach! Du meinst von aussen?! Nochmal: man reicht nicht Daten rum, sondern Objekte.

_________________
"Stil ist ein richtiges Weglassen des Unwesentlichen." - Anselm Feuerbach
scrub
Mitglied

Benutzerprofil
Anmeldungsdatum: 17.09.2004
Beiträge: 3500
Beitrag scrub Mitglied 20:50:18 16.03.2008   Titel:              Zitieren

Natürlich kann man einen Öltanker auch selbst mit dem Zollstock abmessen. Aber wäre es nicht wesentlich einfacher, der Konstrukteur sagt mir einfach, wie lang das Schiff ist?

_________________
"Ich gehöre nicht zu denen, die die Bundesrepublik ruinieren wollen. Ich hoffe, Sie machen noch Halt, Herr Kohl, ehe Sie unwissentlich vieles dazu tun, daß sie ruiniert wird!"


Zuletzt bearbeitet von scrub am 20:50:29 16.03.2008, insgesamt 1-mal bearbeitet
Knuddlbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.12.2001
Beiträge: 5237
Beitrag Knuddlbaer Mitglied 20:54:14 16.03.2008   Titel:              Zitieren

Apollon schrieb:
Knuddlbaer schrieb:
und wie kommt man an die nötigen Daten rann ?

Hoe? Man hat doch freien Zugriff drauf... Ach! Du meinst von aussen?! Nochmal: man reicht nicht Daten rum, sondern Objekte.


Davon das Du Deine Aussage wiederholst, wird sie nicht besser. Was fange ich mit einem Objekt an, das ich übergeben bekommen habe ? Was bringt mir ein Objekt, das Berechnungen vornimmt wenn man die Daten nicht verwenden kann ?
Artchi
Autor

Benutzerprofil
Anmeldungsdatum: 16.03.2002
Beiträge: 8576
Beitrag Artchi Autor 20:55:25 16.03.2008   Titel:              Zitieren

Badestrand schrieb:
Ich fände so einen Artikel auch interessant! Wie sollte er denn aufgemacht sein? Generelles Klassen-Design vor dem eigentlich Programmieren (also Planung) mit Fallbeispielen oder wie?
Und komplett ohne Getter? Weil einige Daten muss man ja rausholen?

Mir geht es nicht um allgemeines OOD. Mir geht es wirklich um diese Getter/Setter-Sache. Ich pers. kann es mir halt nicht vorstellen. Es gibt natürlich hier und da Situationen, wo man ohne diese auskommt. Aber das klassische Beispiel ist z.B. das mit dem Modell. Oder ein anderes Beispiel:

C/C++ Code:
class Widget
{
   public:
      void setPosition(Point);
      Point getPosition();
};
C/C++ Code:
class Widget
{
public:
void setPosition(Point);
Point getPosition();
};
C/C++ Code:
class Widget
{
   public:
      void setPosition(Point);
      Point getPosition();
};


Sorry, aber wenn etwas eine Eigenschaft hat (z.B. eine 2D-Koordinate), wie soll ich das anders machen?
Und size() von vector ist auch nur ein getter. Genauso wie resize() auch ein setter ist. Fehlt nur das Prefix set oder get bzw. sie heißen anders. Aber der Effekt ist der gleiche.

Oberes Beispiel würde wohl so werden:
C/C++ Code:
class Widget
{
   public:
      void move(Point);   // das gleiche wie setPosition
      Point position();   // das gleiche wie getPosition
};
C/C++ Code:
class Widget
{
public:
void move(Point); // das gleiche wie setPosition
Point position(); // das gleiche wie getPosition
};
C/C++ Code:
class Widget
{
   public:
      void move(Point);   // das gleiche wie setPosition
      Point position();   // das gleiche wie getPosition
};


Ist aber am Ende auch nur getter/setter.

Also, mich würden solche realen Szenarios interessieren, wenn ich eine Entität habe (wie das Model im MVC-Pattern!). Weil normalerweise bekommt man nur zurecht geschnittene Szenarios präsentiert. Aber es gibt soviele GUI-Libs die alle mit getter/setter arbeiten... ich wills jetzt endlich mal konkret wissen, wie man das anders lösen könnte.

_________________
Bring back the Windows Start Menu Petition | GoPetition


Zuletzt bearbeitet von Artchi am 20:58:51 16.03.2008, insgesamt 2-mal bearbeitet
scrub
Mitglied

Benutzerprofil
Anmeldungsdatum: 17.09.2004
Beiträge: 3500
Beitrag scrub Mitglied 20:58:22 16.03.2008   Titel:              Zitieren

Du machst den Koordinatenpunkt public. Da die Semantik von set es sowieso nicht zuläßt, Konsistenzprüfungen vorzunehmen, brauchst Du natürlich auch keinen Setter mehr. Und für eine public Koordinate brauchst Du natürlich auch keinen Getter mehr.

_________________
"Ich gehöre nicht zu denen, die die Bundesrepublik ruinieren wollen. Ich hoffe, Sie machen noch Halt, Herr Kohl, ehe Sie unwissentlich vieles dazu tun, daß sie ruiniert wird!"
Badestrand
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2006
Beiträge: 4342
Beitrag Badestrand Mitglied 21:00:34 16.03.2008   Titel:              Zitieren

scrub schrieb:
Du machst den Koordinatenpunkt public. Da die Semantik von set es sowieso nicht zuläßt, Konsistenzprüfungen vorzunehmen, brauchst Du natürlich auch keinen Setter mehr. Und für eine public Koordinate brauchst Du natürlich auch keinen Getter mehr.
In dem GUI-Fall musst du aber auf die Positions-Veränderung reagieren, indem du dein Widget verschiebst. So einfach ist es dann doch nicht.
scrub
Mitglied

Benutzerprofil
Anmeldungsdatum: 17.09.2004
Beiträge: 3500
Beitrag scrub Mitglied 21:03:29 16.03.2008   Titel:              Zitieren

Naja, ich vertrete die Meinung auch nicht selbst, sondern das ist das, was ich davon verstehe. Ich finde es auch nicht sinnvoll. Insofern habe ich keine Ahnung, wie das Problem in einer "in dem GUI-Fall" damit anzugehen wäre.

_________________
"Ich gehöre nicht zu denen, die die Bundesrepublik ruinieren wollen. Ich hoffe, Sie machen noch Halt, Herr Kohl, ehe Sie unwissentlich vieles dazu tun, daß sie ruiniert wird!"


Zuletzt bearbeitet von scrub am 21:03:40 16.03.2008, insgesamt 1-mal bearbeitet
Artchi
Autor

Benutzerprofil
Anmeldungsdatum: 16.03.2002
Beiträge: 8576
Beitrag Artchi Autor 21:04:01 16.03.2008   Titel:              Zitieren

Knuddlbaer schrieb:
Apollon schrieb:
Knuddlbaer schrieb:
und wie kommt man an die nötigen Daten rann ?

Hoe? Man hat doch freien Zugriff drauf... Ach! Du meinst von aussen?! Nochmal: man reicht nicht Daten rum, sondern Objekte.


Davon das Du Deine Aussage wiederholst, wird sie nicht besser. Was fange ich mit einem Objekt an, das ich übergeben bekommen habe ? Was bringt mir ein Objekt, das Berechnungen vornimmt wenn man die Daten nicht verwenden kann ?

Beispiel MVC-Pattern: ich muß doch wissen, woher ich die Daten des Models bekomme, wenn ich das View bin.

Eine andere Möglichkeit wäre, das ich beim Update gleich die Daten bekomme.
C/C++ Code:
class Widget
{
     public:
          void update(Model);
};
C/C++ Code:
class Widget
{
public:
void update(Model);
};
C/C++ Code:
class Widget
{
     public:
          void update(Model);
};

Wäre eine Möglichkeit. Aber wie soll sich die View (Widget) beim Model abmelden, wenn es das Model nicht kennt? Man könnte es extern lösen, aber wäre es nicht einfacher, wenn sich das Widget selber im Dtor vom Model abmeldet? Dazu muß ich aber ein Widget::setModel(Model) haben...

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
class Widget
{
     Model *model;
     public:
          void setModel(Model *m)
          {
               model = m;
          }
          ~Widget()
          {
               model->remove(this); // beim Model abmelden
          }
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Widget
{
Model *model;
public:
void setModel(Model *m)
{
model = m;
}
~Widget()
{
model->remove(this); // beim Model abmelden
}
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Widget
{
     Model *model;
     public:
          void setModel(Model *m)
          {
               model = m;
          }
          ~Widget()
          {
               model->remove(this); // beim Model abmelden
          }
};


Ihr merkt, hier ist einfach Praxismangel vorhanden, wenn man ohne Getter/Setter auskommen soll.

_________________
Bring back the Windows Start Menu Petition | GoPetition


Zuletzt bearbeitet von Artchi am 21:06:49 16.03.2008, insgesamt 1-mal bearbeitet
Artchi
Autor

Benutzerprofil
Anmeldungsdatum: 16.03.2002
Beiträge: 8576
Beitrag Artchi Autor 21:08:20 16.03.2008   Titel:              Zitieren

scrub schrieb:
Du machst den Koordinatenpunkt public. Da die Semantik von set es sowieso nicht zuläßt, Konsistenzprüfungen vorzunehmen, brauchst Du natürlich auch keinen Setter mehr. Und für eine public Koordinate brauchst Du natürlich auch keinen Getter mehr.

Public-Variablen widerspricht aber der OO-Philosophie! Und außerdem will ich sehr wohl eine Prüfung beim setPosition (oder move) durchführen, z.B. keine negativen Koordinaten erlauben.

_________________
Bring back the Windows Start Menu Petition | GoPetition
scrub
Mitglied

Benutzerprofil
Anmeldungsdatum: 17.09.2004
Beiträge: 3500
Beitrag scrub Mitglied 21:11:15 16.03.2008   Titel:              Zitieren

Mir wurde und wird aber entgegnet, dies sei durch "die Semantik" von Set verboten. Setter dürfen nicht auf Konsistenz prüfen, heißt es.
Das ist wirklich kein Witz und keine Erfindung von mir... das ist die Argumentation. Der Setter darf nur setzen, sonst nichts. Also kann man, wenn man einen Setter anbietet, die Variable auch gleich public machen.

_________________
"Ich gehöre nicht zu denen, die die Bundesrepublik ruinieren wollen. Ich hoffe, Sie machen noch Halt, Herr Kohl, ehe Sie unwissentlich vieles dazu tun, daß sie ruiniert wird!"


Zuletzt bearbeitet von scrub am 21:14:38 16.03.2008, insgesamt 2-mal bearbeitet
Badestrand
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2006
Beiträge: 4342
Beitrag Badestrand Mitglied 21:53:30 16.03.2008   Titel:              Zitieren

Gewisse Getter brauchst du auf jeden Fall, sonst bringen dir deine Objekte oft wirklich nichts. Ein Datei-Objekt muss beim Lesen halt die Daten der Datei zurückgeben, anders gehts nicht. In bestimmten Fällen (vor allem bei GUI-Sachen) geht's wahrscheinlich auch oft nicht "besser".
Oft kann man gerade Setter aber verhindern, indem ein Objekt bei der Konstruktion Daten mitbekommt (oder es sich diese erarbeitet) und diese nur noch abfragbar sind.

Aber ich denke, man muss da sowieso noch mehr differenzieren. Eine Klasse, die nach dem Getter-/Setter-Prinzip designed ist, unterscheidet sich ja in der Konzeption schon sehr stark von einer Klasse, die darauf nicht ausgelegt ist.

Beispiel (hoffentlich kein zurecht-geschnittenes Szenario): Wir haben eine Klasse, die eine Datei repräsentiert. Die Datei kann Integer speichern, umbenannt, verschoben, ausgelesen und beschrieben werden.
Getter/Setter:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class DateiManager
{
    Datei getDatei( pfad )       // Gibt entsprechendes Datei-Objekt zurück
}

class Datei
{
    void setContent( int i[] )
    int[] getContent()

    string getName()
    void setName( name ) // benennt Datei um

    string getPath()
    void setPath( path ) // verschiebt Datei
}
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class DateiManager
{
Datei getDatei( pfad ) // Gibt entsprechendes Datei-Objekt zurück
}

class Datei
{
void setContent( int i[] )
int[] getContent()

string getName()
void setName( name ) // benennt Datei um

string getPath()
void setPath( path ) // verschiebt Datei
}
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class DateiManager
{
    Datei getDatei( pfad )       // Gibt entsprechendes Datei-Objekt zurück
}

class Datei
{
    void setContent( int i[] )
    int[] getContent()

    string getName()
    void setName( name ) // benennt Datei um

    string getPath()
    void setPath( path ) // verschiebt Datei
}

Anderes Design:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class DateiManager
{
   Datei getFile( pfad )                 // Gibt entsprechendes Datei-Objekt zurück
   void moveFile( src_path, dst_path )   // Verschiebt Datei
   void renameFile( src_path, new_name ) // Benennt Datei um, meinetwegen auch setFileName(...)
}

class Datei
{
    void clear()                         // Leert Inhalt
    int read()                           // Liest einen Integer
    void write( int i )                  // Schreibt Integer
    int seek( int pos )                  // Bewegt den Dateizeiger

    // Zu beachten: Datei kennt weder ihren Pfad noch ihren Namen!
}
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class DateiManager
{
Datei getFile( pfad ) // Gibt entsprechendes Datei-Objekt zurück
void moveFile( src_path, dst_path ) // Verschiebt Datei
void renameFile( src_path, new_name ) // Benennt Datei um, meinetwegen auch setFileName(...)
}

class Datei
{
void clear() // Leert Inhalt
int read() // Liest einen Integer
void write( int i ) // Schreibt Integer
int seek( int pos ) // Bewegt den Dateizeiger

// Zu beachten: Datei kennt weder ihren Pfad noch ihren Namen!
}
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class DateiManager
{
   Datei getFile( pfad )                 // Gibt entsprechendes Datei-Objekt zurück
   void moveFile( src_path, dst_path )   // Verschiebt Datei
   void renameFile( src_path, new_name ) // Benennt Datei um, meinetwegen auch setFileName(...)
}

class Datei
{
    void clear()                         // Leert Inhalt
    int read()                           // Liest einen Integer
    void write( int i )                  // Schreibt Integer
    int seek( int pos )                  // Bewegt den Dateizeiger

    // Zu beachten: Datei kennt weder ihren Pfad noch ihren Namen!
}


Das ist ganz sicher kein Ideal-Beispiel, aber ich denke, ein paar wesentliche Punkte sind drin: Objekt gibt nur nötigste Informationen raus (Datei gibt nur den Inhalt, nicht Namen oder Pfad), Verantwortung liegt so hoch wie möglich (Dateimanager ist für's Datei-verschieben zuständig, nicht die Datei) und differenziertere Methoden (clear, seek, write vs setContent).


Artchi schrieb:
Beispiel MVC-Pattern: ich muß doch wissen, woher ich die Daten des Models bekomme, wenn ich das View bin.
Das einzig sinnvolle beim MVC finde ich, den Datenbestand als Singleton zu halten (was spräche dagegen?).

Code:
class Widget
{
   public:
      void setPosition(Point);
      Point getPosition();
};
Code:
class Widget
{
public:
void setPosition(Point);
Point getPosition();
};
Code:
class Widget
{
   public:
      void setPosition(Point);
      Point getPosition();
};

:arrow:
Code:
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
class Widget
{
}

class WidgetParent/-Container/-Manager/-Holder
{
    void addWidget( widget, position )
    void setWidgetPosition( widgetID, new_position )
}
Code:
1
2
3
4
5
6
7
8
9
class Widget
{
}

class WidgetParent/-Container/-Manager/-Holder
{
void addWidget( widget, position )
void setWidgetPosition( widgetID, new_position )
}
Code:
1
2
3
4
5
6
7
8
9
class Widget
{
}

class WidgetParent/-Container/-Manager/-Holder
{
    void addWidget( widget, position )
    void setWidgetPosition( widgetID, new_position )
}

Du kommst nicht drumherum, eine Methode zu haben um die Position des Widgets zu setzen, schließlich braucht man die Funktionalität. Wenn man sowieso die Funktionalität braucht (die zum Auslesen der Position braucht man z.B. nicht), ist es nur noch die Frage, in welcher Form und bei welcher Zuständigkeit man die Methode implementiert. Und diese beiden Sachen, zusätzlich zu der Entscheidung ob man eine Funktionalität braucht, sind es meiner Meinung nach, die dann das Getter/Setter-Design ausmachen oder auch nicht.


PS: Ich gebe zu, das Beispiel mit der Datei ist etwas schwammig. Ich hab mich bisher auch noch nie groß mit der Getter/Setter-Frage beschäftigt, mir ist aber aufgefallen, dass ich in meinen Quelltexten quasi fast gar keine Setter/Getter-Kaskaden eingebaut hab und an der Arbeit baue ich auch ab und an Getter/Setter aus (und das Design verbessert sich imho dadurch).


Zuletzt bearbeitet von Badestrand am 22:00:07 16.03.2008, insgesamt 4-mal bearbeitet
code_drechsler
Unregistrierter




Beitrag code_drechsler Unregistrierter 04:07:47 17.03.2008   Titel:              Zitieren

Ich bin jetzt noch recht neu in C++.
Nur irgendwie verstehe ich die Diskussion nicht ganz.
Natürlich ist es so, das ich niemals einen getter schreibe, wenn ich von Anfang an weiss, das ich niemals mehr den Wert mehr auslesen brauche, sondern dieser nur für interne Berechnungen z.B. in der Klasse notwendig ist.
Oder schreibt jemand einen Getter grundsätzlich für alle Member Variablen ?
Aber sobald ich irgendwie auf meine private Member Variablen zugreifen will ob nun zum setzen oder zum lesen, ist es doch immer eine Setter bzw. Getter Methode, egal wie ich sie nenne.
Wenn ich die private dann einfach in den public Part packe, dann brauche ich zwar keine Getter/Setter, aber das widerspricht doch dem Grundgedanken der OO.
Und die Argumentation, das man anstelle des getters dann einfach das Objekt zurückgibt kann ich irgendwie auch nicht Ansatzweise nachvollziehen. Ich will ja nunmal an die privates des Objektes ran. Und das geht ja nur über eine getter.
Bitte klärt mich mal jemand auf, ob ich da was komplett missverstanden habe.
:confused:
Apollon
Mitglied

Benutzerprofil
Anmeldungsdatum: 22.04.2003
Beiträge: 1879
Beitrag Apollon Mitglied 06:36:16 17.03.2008   Titel:              Zitieren

Was reicht ihr weiter (in einem C+-Programm): einen string oder einen char-array? Einen vector oder die interne Repraesentation davon?

Im Uebrigen stammt die Argumentation, mit der scrub konfrontiert wurde in erster Linie von mir.

_________________
"Stil ist ein richtiges Weglassen des Unwesentlichen." - Anselm Feuerbach


Zuletzt bearbeitet von Apollon am 06:40:35 17.03.2008, insgesamt 1-mal bearbeitet
Artchi
Autor

Benutzerprofil
Anmeldungsdatum: 16.03.2002
Beiträge: 8576
Beitrag Artchi Autor 10:59:37 17.03.2008   Titel:              Zitieren

Zitat:
Was reicht ihr weiter (in einem C+-Programm): einen string oder einen char-array? Einen vector oder die interne Repraesentation davon?

Versteh den Vergleich nicht. Vector und String sind Typen, richtig. Aber diese Typen werden dadurch "besonders" das sie bestimmte Eigenschaften haben. Und diese Eigenschaften sind vielfältig: Einzelne Elemente, Anzahl Elemente, Reservierte Elemente usw. So, und wie komme ich an diese Eigenschaften ran? Über getter und setter (nur heißen die nicht so, Namen sind Schall und Rauch):

C/C++ Code:
string str("Hallo");
char a = str.at(0);   // Getter auf ein Element 0, heißt nur nicht get()!
str.at(0) = 'B';      // Setter auf ein Element 0!
str.c_str();       // Getter auf alle Elemente
size_t s = str.size();  // Getter auf Eigenschaft Länge, heißt nur nicht get_size()
str.resize(100); // Setter auf Eigenschaft Länge, heißt nur nicht set_size()
C/C++ Code:
string str("Hallo");
char a = str.at(0); // Getter auf ein Element 0, heißt nur nicht get()!
str.at(0) = 'B'; // Setter auf ein Element 0!
str.c_str(); // Getter auf alle Elemente
size_t s = str.size(); // Getter auf Eigenschaft Länge, heißt nur nicht get_size()
str.resize(100); // Setter auf Eigenschaft Länge, heißt nur nicht set_size()
C/C++ Code:
string str("Hallo");
char a = str.at(0);   // Getter auf ein Element 0, heißt nur nicht get()!
str.at(0) = 'B';      // Setter auf ein Element 0!
str.c_str();       // Getter auf alle Elemente
size_t s = str.size();  // Getter auf Eigenschaft Länge, heißt nur nicht get_size()
str.resize(100); // Setter auf Eigenschaft Länge, heißt nur nicht set_size()

Natürlich übergebe ich str an eine Funktion, wenn sie einen string haben will. Aber das bestimme nicht ich, sondern die Funktion, die ich benutzen will.

Und genau das gleich wie Widget: ich habe Widget, das reiche ich weiter, wenn jemand ein Widget haben will. Aber was ist wenn er die Caption oder die XY-Pos des Widgets haben will?

Also wirklich schlau werde ich aus dem Konzept "keine Getter/Setter" nicht. Schön das ich String- oder Widget-Objekte weiter reiche. Macht man ja auch und spricht nichts dagegen. Aber gaaanz am Ende muß man ja auf die Eigenschaften eines Objektes zugreifen. Wie soll das ohne Getter/Setter gehen? Oder geht es am Ende doch nur um die Namesgebung einer Member-Funktion? :D

_________________
Bring back the Windows Start Menu Petition | GoPetition


Zuletzt bearbeitet von Artchi am 11:10:59 17.03.2008, insgesamt 4-mal bearbeitet
Knuddlbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.12.2001
Beiträge: 5237
Beitrag Knuddlbaer Mitglied 11:20:42 17.03.2008   Titel:              Zitieren

Zitat:
Im Uebrigen stammt die Argumentation, mit der scrub konfrontiert wurde in erster Linie von mir.



Dann bin ich jetzt mal auf die Argumentation gespannt, warum ein Setter keine Prüfungen vornehmen darf. Die Argumentation des Getters und deren Objekte ist ja schon recht verdreht (siehe Artchi mit der Ausführung der Getter beim String Objekt), so das die Argumentation für Setter sicherlich sehr interessant wird :o)


Zuletzt bearbeitet von Knuddlbaer am 11:21:41 17.03.2008, insgesamt 1-mal bearbeitet
forensiker
Unregistrierter




Beitrag forensiker Unregistrierter 11:30:00 17.03.2008   Titel:              Zitieren

Zitat:
Dann bin ich jetzt mal auf die Argumentation gespannt, warum ein Setter keine Prüfungen vornehmen darf.

Das ist absoluter Quatsch. Natürlich kann ein Setter Gültigkeitsprüfungen übernehmen. Nur weil er einfach nur Setter heisst, muss er ja nicht nur das tun. Da gibt es vielleicht Leute, die das so für sich festlegen, und dann als goldene Regel verkaufen wollen.
DEvent
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.12.2003
Beiträge: 3270
Beitrag DEvent Mitglied 13:31:01 17.03.2008   Titel:              Zitieren

Also erstmal ich verstehe die ganze Diskussion ueberhaupt nicht. Was haben die Leute nur gegen getter/setter, bis auf tipparbeit ist es genau gleich wie direkt auf Attribute zugreifen, aber mit wesentlichen Vorteilen.

Man sollte eher einen Artikel schreiben das man immer setter/getter verwenden sollte und wie man in C++ die Perfomance steigern kann, bzw. wie man keine Perfomance-Einbußen hat, wenn man getter/setter verwendet.

Zitat:
Das ist ganz sicher kein Ideal-Beispiel, aber ich denke, ein paar wesentliche Punkte sind drin: Objekt gibt nur nötigste Informationen raus (Datei gibt nur den Inhalt, nicht Namen oder Pfad), Verantwortung liegt so hoch wie möglich (Dateimanager ist für's Datei-verschieben zuständig, nicht die Datei) und differenziertere Methoden (clear, seek, write vs setContent).
Die Aufgabe einer Datei ist es aber ihren Pfad und Namen zu kennen. Das was du beschrieben hast sind die Daten einer Datei und nicht die Datei selbst.

Eine Datei stellt nunmal eine Verbindung her zwischen einem Bezeichner (Pfad+Name) und den Daten selber. Ob sich eine Datei dabei selbst loeschen/kopieren/unbennen kann, ist eine andere Diskussion.

_________________
http://www.globalscaling.de/
http://www.globalscalingsoftware.de/
Badestrand
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2006
Beiträge: 4342
Beitrag Badestrand Mitglied 16:58:37 17.03.2008   Titel:              Zitieren

DEvent schrieb:
Man sollte eher einen Artikel schreiben das man immer setter/getter verwenden sollte und wie man in C++ die Perfomance steigern kann, bzw. wie man keine Perfomance-Einbußen hat, wenn man getter/setter verwendet.
Es geht doch gar nicht um Performance, sondern um stilistische Vor-/Nachteile, z.B. wie gut der Code wartbar, erweiterbar oder die Implementation austauschbar ist.

DEvent schrieb:
Die Aufgabe einer Datei ist es aber ihren Pfad und Namen zu kennen. Das was du beschrieben hast sind die Daten einer Datei und nicht die Datei selbst.

Wir scheinen verschiedene Auffassungen von Aufgaben von Objekten zu haben. Es ist meiner Meinung nach ungünstig, jedes Objekt als Eigenschaften-Container zu betrachten und sich zu fragen: "Was hat das Objekt?"; und das, was das Objekt hat (seine Eigenschaften), kann man dann auslesen und/oder setzen.
Es ist doch imho erstrebenswerter, sich zu fragen, welche Aufgabe ein Objekt hat, was es also kann. Man steuert damit dann auf eine Schnittstelle zu, die definiert, zu was das Objekt in der Lage ist, und nicht, welche Daten es enthält. Denn das kann uns als Benutzer des Objekts doch völlig egal sein.

Das ist ja auch das tolle an der Trennung von View und Datenmodell: Es ist uns völlig egal, welche Daten das Modell hat, solange es unsere Befehle befolgt und die richtigen Antworten gibt. Sicher ist das aber oft ein sehr schmaler Grad zwischen Anforderungen und Daten-haben.

Was ich oft sehe, wie die Trennung von View und Datenmodell missbraucht wird: Das Modell dient nur als Container, dient als Getter/Setter-Schnittstelle für die dahinterstehenden Daten. Soll dann aus dem View ein Datensatz irgendwo in das Datenmodell eingefügt werden, sieht das meist so aus: DataModel::Instance()->getThis()->getThat()->getDataSet()->insertData( ... );. Das ist imo aber völlig schwachsinnig, weil man damit eine bestimmte Implementierung auf der Modell-Seite voraussetzt. Es wird halt das Modell nur als Container angesehen und wird nur benutzt, um auf die dahinterliegenden Datenstrukturen zuzugreifen. Eigentlich sollte es aber so sein, dass das View die dahinterliegenden Datenstrukturen gar nicht kennen sollte oder sogar darf, weil das eben ein Implementierungsdetail ist.
Wenn wir unser Modell aber so modellieren, dass es bestimmte Anforderungen zu erfüllen hat, sieht das ganze schon anders aus. Als View haben wir dann einfach nur eine Schnittstelle, nämlich die Methoden vom Modell und nix dahinter. Da unser Modell die Anforderungen zu erfüllen hat, einen Datensatz zu irgendwas hinzuzufügen, muss der Aufruf so aussehen: DataModel::Instance()->insertThisThatData( ... );.

Das hat auch eine Menge Vorteile, es ist viel flexibler und sicherer. Sicherer ist es, da das gesamte Datenmodell nur einen einzigen Eingang hat, nämlich seine eigenen Methoden. Dadurch kann man Inkonsistenzen vermeiden, weil man den absoluten Überblick hat, wo genau Benutzerdaten reinkommen. Mit einem Modell als Container hast du unübersichtlich viele Interaktionspunkte, quer verteilt über das ganze Modell.
Flexibler ist es, weil das Austauschen des Modells absolut trivial ist. Es könnten zwei Modelle völlig unabhängig voneinander entwickelt werden, die im Inneren eine völlig unterschiedliche Datenstruktur haben, sie müssen eben nur die _eine_ Schnittstelle erfüllen. Du könntest das Modell sogar als Internet-Service implementieren, die Schnittstelle mit dem das View interagiert, macht einfach ein paar RPCs.
phloxxx
Unregistrierter




Beitrag phloxxx Unregistrierter 17:21:28 17.03.2008   Titel:              Zitieren

Aus welchem Grund sollte es egal sein welche Daten ein Objekt enthält.Das kann bei manchen Klassen zutreffen, das dir die Daten egal sein können, weil du sie nicht zur weiteren Interaktion benötigst. Sobald wir aber konkret die Daten des Objektes benötigen brauchen wir Zugriff über einen Getter.
Das
C/C++ Code:
DataModel::Instance()->insertThisThatData( ... );
C/C++ Code:
DataModel::Instance()->insertThisThatData( ... );
C/C++ Code:
DataModel::Instance()->insertThisThatData( ... );

ist auch nur ein gewöhnlicher Setter. Ob du nun über den Setter deine komplette Datenstruktur füllst oder aber nur eine Member ist dabei irrelevant.
Badestrand
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2006
Beiträge: 4342
Beitrag Badestrand Mitglied 17:32:32 17.03.2008   Titel:              Zitieren

phloxxx schrieb:
Aus welchem Grund sollte es egal sein welche Daten ein Objekt enthält.Das kann bei manchen Klassen zutreffen, das dir die Daten egal sein können, weil du sie nicht zur weiteren Interaktion benötigst. Sobald wir aber konkret die Daten des Objektes benötigen brauchen wir Zugriff über einen Getter.

Wenn du konkrete Daten brauchst, kannst du immer noch eine Schnittstellen-Struktur entwerfen, die alle benötigten Daten trägt. Man sollte die Schnittstellen-Daten-Struktur aber nicht davon abhängig machen, welche Repräsentation der Daten im inneren des Modells benutzt wird. Denn das ist die Sache des Modells und nicht der Schnittstelle.

phloxxx schrieb:
Das
C/C++ Code:
DataModel::Instance()->insertThisThatData( ... );
C/C++ Code:
DataModel::Instance()->insertThisThatData( ... );
C/C++ Code:
DataModel::Instance()->insertThisThatData( ... );

ist auch nur ein gewöhnlicher Setter. Ob du nun über den Setter deine komplette Datenstruktur füllst oder aber nur eine Member ist dabei irrelevant.
Hast du den Unterschied zu dem Aufruf von DataModel::Instance()->getThis()->getThat()->getDataSet()->insertData( ... ); verstanden?
SideWinder
Moderator

Benutzerprofil
Anmeldungsdatum: 19.10.2001
Beiträge: 18220
Beitrag SideWinder Moderator 17:34:54 17.03.2008   Titel:              Zitieren

Sieht mir sehr danach aus, dass C++ Properties als Sprachfeature fehlen?!

MfG SideWinder
Badestrand
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2006
Beiträge: 4342
Beitrag Badestrand Mitglied 17:37:39 17.03.2008   Titel:              Zitieren

Huch, woher hast du das jetzt abgeleitet?
Bashar
Mitglied

Benutzerprofil
Anmeldungsdatum: 15.05.2001
Beiträge: 16812
Beitrag Bashar Mitglied 17:47:29 17.03.2008   Titel:              Zitieren

Ich erwähne dazu mal ein Designprinzip namens Law of Demeter, das besagt, dass man nur Nachrichten an Objekte senden darf (sollte), die man besitzt, kennt (als Referenz hält) oder selbst erzeugt hat, nicht aber an solche, die man von anderen Objekten lediglich angefordert hat. Sowas ist also verboten:
C/C++ Code:
obj->getFoo()->doSomething();
C/C++ Code:
obj->getFoo()->doSomething();
C/C++ Code:
obj->getFoo()->doSomething();

Das läuft auch unter dem Namen "Tell, don't ask". Sag dem Objekt, was es tun soll; lass dir nicht irgendwelche Interna geben und manipuliere diese.

_________________
OSL♥
Kenner des SideWinder
Unregistrierter




Beitrag Kenner des SideWinder Unregistrierter 18:15:44 17.03.2008   Titel:              Zitieren

SideWinder schrieb:
Sieht mir sehr danach aus, dass C++ Properties als Sprachfeature fehlen?!

MfG SideWinder
:die: Du willst doch nur einen Flamewar provozieren. :warning:
DEvent
Mitglied

Benutzerprofil
Anmeldungsdatum: 27.12.2003
Beiträge: 3270
Beitrag DEvent Mitglied 12:20:02 18.03.2008   Titel:              Zitieren

Zitat:
Wir scheinen verschiedene Auffassungen von Aufgaben von Objekten zu haben. Es ist meiner Meinung nach ungünstig, jedes Objekt als Eigenschaften-Container zu betrachten und sich zu fragen: "Was hat das Objekt?"; und das, was das Objekt hat (seine Eigenschaften), kann man dann auslesen und/oder setzen.
Es ist doch imho erstrebenswerter, sich zu fragen, welche Aufgabe ein Objekt hat, was es also kann. Man steuert damit dann auf eine Schnittstelle zu, die definiert, zu was das Objekt in der Lage ist, und nicht, welche Daten es enthält. Denn das kann uns als Benutzer des Objekts doch völlig egal sein.
Ich stimm dir doch zu, allerdings hast du mit deinem "Datei" eher die Daten beschrieben, nicht eine Datei. Deine Datei hat nur Methoden um auf die Daten zuzugreifen, aber nichts um auf die Datei zuzugreifen.

Egal ist eh OT.

Zitat:
Es geht doch gar nicht um Performance, sondern um stilistische Vor-/Nachteile, z.B. wie gut der Code wartbar, erweiterbar oder die Implementation austauschbar ist.
Dann verstehe ich die Diskussion erst recht nicht.

Geht es darum statt getter/setter direkt auf die Attribute zuzugreifen?

Denn getter/setter benoetigst du auf jeden Fall, und wenn du sie statt setXXX/getXXX eben read(), write() und seek() nennst. Wenn du das Kind Max statt Alex nennst, bleibst es doch ein Kind. ;)

Edit:
Zitat:
Hast du den Unterschied zu dem Aufruf von DataModel::Instance()->getThis()->getThat()->getDataSet()->insertData( ... ); verstanden?
Ah darum gehts? Dann heist der Artikel: Abstraktion von Internen Strukturen und deren Vorteil vs direkten Zugriff auf alles?

_________________
http://www.globalscaling.de/
http://www.globalscalingsoftware.de/


Zuletzt bearbeitet von DEvent am 12:26:26 18.03.2008, insgesamt 1-mal bearbeitet
Artchi
Autor

Benutzerprofil
Anmeldungsdatum: 16.03.2002
Beiträge: 8576
Beitrag Artchi Autor 12:50:27 18.03.2008   Titel:              Zitieren

Zitat:
Zitat:
Zitat:
Hast du den Unterschied zu dem Aufruf von DataModel::Instance()->getThis()->getThat()->getDataSet()->insertData( ... ); verstanden?

Ah darum gehts? Dann heist der Artikel: Abstraktion von Internen Strukturen und deren Vorteil vs direkten Zugriff auf alles?

Dann geht es doch aber nicht generell um getter/setter? Sondern darum, ob ich mir eine Abhängigkeit in meinem Code aufbaue, oder durch eine betsimmte Methode den get-get-Strang verstecke?

Also, irgendwie stehe ich immer noch im Regen. Zuerst kristalisierte sich mehr heraus, das es an der Namensgebung liegt (setSize vs. resize) obwohl es in der Implementierung gleich ist. Doch jetzt gehts anscheinend "nur" um die zu vermeidende Abhängigkeit? (was Sinn macht)

Entweder ist jemand so nett und schreibt einen schönen Artikel darüber, wo wir aufgeklärt werden, oder ich sollte in Zukunft so weiter machen ohne Zweifel ("Oh nein, getter/setter sind doch angeblich schlecht, was mache ich jetzt?"). :)

_________________
Bring back the Windows Start Menu Petition | GoPetition


Zuletzt bearbeitet von Artchi am 12:54:31 18.03.2008, insgesamt 2-mal bearbeitet
Badestrand
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2006
Beiträge: 4342
Beitrag Badestrand Mitglied 12:56:33 18.03.2008   Titel:              Zitieren

DEvent schrieb:
Badestrand schrieb:
Es geht doch gar nicht um Performance, sondern um stilistische Vor-/Nachteile, z.B. wie gut der Code wartbar, erweiterbar oder die Implementation austauschbar ist.
Dann verstehe ich die Diskussion erst recht nicht.
Also ich denke nicht, dass es generell bei Getter/Setter vs anders um Performance geht, das dürfte sich wahrscheinlich ziemlich die Waage halten.

DEvent schrieb:
Denn getter/setter benoetigst du auf jeden Fall, und wenn du sie statt setXXX/getXXX eben read(), write() und seek() nennst. Wenn du das Kind Max statt Alex nennst, bleibst es doch ein Kind. ;)
Hehe, das ist wahr :) Naja, es ist imo ein wenig schwierig zu definieren, was nun ein Getter/Setter ist. Wenn Getter einfach alle Methoden sind, mit denen man sich Informationen aus dem Objekt holt und Setter alle befehlsartigen Methoden sind, dann sind sie definitiv unverzichtbar, Objekte könnten ja sonst gar nicht kommunizieren.
Ich verstehe unter Gettern und Settern aber eher eine spezielle Art von Methoden, ich will's mal versuchen darzustellen:
Code:
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
class Sonstwas
{
public:
    void SetFoo( Foo* p ) {ptr=p;}
    Foo* GetFoo()         {return ptr;}

private:
    Foo* ptr;
}
Code:
1
2
3
4
5
6
7
8
9
class Sonstwas
{
public:
void SetFoo( Foo* p ) {ptr=p;}
Foo* GetFoo() {return ptr;}

private:
Foo* ptr;
}
Code:
1
2
3
4
5
6
7
8
9
class Sonstwas
{
public:
    void SetFoo( Foo* p ) {ptr=p;}
    Foo* GetFoo()         {return ptr;}

private:
    Foo* ptr;
}

Etwa so halt, wie Artchi das mit dem pModel bei MVC skizziert hatte; man hat ein Objekt und setzt ihm ein bestimmtes Objekt rein oder holt es heraus. Oder auch Klassen, bei denen quasi alle Attribute abfragbar und setzbar sind:
Code:
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
class Sonstwas
{
public:
    // Hier Getter und Setter für jedes Attribut.
private:
    int attr1;
    str attr2;
    foo attr3;
}
Code:
1
2
3
4
5
6
7
8
9
class Sonstwas
{
public:
// Hier Getter und Setter für jedes Attribut.
private:
int attr1;
str attr2;
foo attr3;
}
Code:
1
2
3
4
5
6
7
8
9
class Sonstwas
{
public:
    // Hier Getter und Setter für jedes Attribut.
private:
    int attr1;
    str attr2;
    foo attr3;
}


DEvent schrieb:
Ah darum gehts? Dann heißt der Artikel: Abstraktion von Internen Strukturen und deren Vorteil vs direkten Zugriff auf alles?
Vielleicht, ja :D Nein, aber genau solche Aufruf-Kaskaden bekommt man oft, wenn man mit obigen Gettern/Settern arbeitet.

Tut mir Leid, wenn ich anscheinend ein wenig am Thema vorbeigeredet hab :)
Badestrand
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2006
Beiträge: 4342
Beitrag Badestrand Mitglied 13:29:50 18.03.2008   Titel:              Zitieren

PS: Was wären für euch denn Methoden, die weder Getter noch Setter sind?
ich_du_er
Unregistrierter




Beitrag ich_du_er Unregistrierter 15:25:30 18.03.2008   Titel:              Zitieren

Badestrand schrieb:
PS: Was wären für euch denn Methoden, die weder Getter noch Setter sind?
Aktionen. foo.do_something();
Artchi
Autor

Benutzerprofil
Anmeldungsdatum: 16.03.2002
Beiträge: 8576
Beitrag Artchi Autor 15:29:08 18.03.2008   Titel:              Zitieren

Zitat:
Etwa so halt, wie Artchi das mit dem pModel bei MVC skizziert hatte; man hat ein Objekt und setzt ihm ein bestimmtes Objekt rein oder holt es heraus.

Und wie soll das Widget das Model kennen? Es geht dabei nicht darum, das Model zu verwalten, sondern nur zu kennen. Oder wie stellt ihr Verbindungen zu Objekten her?

Am Ende geht es hier anscheinend nur darum, wie die Funktion heißt? Soll heißen, die Anti-Setter-Getter-Fraktion stört sich nur am Funktionsnamen? Denn vorallem bei OOD kann ich nie sagen, was hinter setX wirklich passiert. Wird tatsächlich nur ein Attribut neu gesetzt? Oder passiert da vielleicht nicht doch mehr?

Beispiel MVC:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Pseudocode:

class Widget
{
      Model *model;
public:
      void setModel(Model *m)   // evil?
      {
           model = m;
           model->addObserver(this);
      }

      void observe(Model *m)   // besser weil kein setter-Name???
      {
           model = m;  // set Model!
           model->addObserver(this);
      }
     


      ~Widget()
      {
          model->removeObserver(this);  // wie sonst, wenn es kein set model gibt?
      }
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Pseudocode:

class Widget
{
Model *model;
public:
void setModel(Model *m) // evil?
{
model = m;
model->addObserver(this);
}

void observe(Model *m) // besser weil kein setter-Name???
{
model = m; // set Model!
model->addObserver(this);
}



~Widget()
{
model->removeObserver(this); // wie sonst, wenn es kein set model gibt?
}
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Pseudocode:

class Widget
{
      Model *model;
public:
      void setModel(Model *m)   // evil?
      {
           model = m;
           model->addObserver(this);
      }

      void observe(Model *m)   // besser weil kein setter-Name???
      {
           model = m;  // set Model!
           model->addObserver(this);
      }
     


      ~Widget()
      {
          model->removeObserver(this);  // wie sonst, wenn es kein set model gibt?
      }
};

Klar, observe() als Funktionsname ist nicht schlecht. Aber die Implementierung ist in beiden Fällen gleich. Man kann also gerne darüber diskutieren, ob man immer den richtigen Namen für eine FUnktion wählt, aber das model = m; schlecht sein soll, kann ich nicht verstehen!!! Ich muß doch irgendwo mir meine Beziehungen merken dürfen, um mit ihnen zu aggieren (siehe z.B. Destruktor!).

_________________
Bring back the Windows Start Menu Petition | GoPetition


Zuletzt bearbeitet von Artchi am 15:34:03 18.03.2008, insgesamt 2-mal bearbeitet
Shade Of Mine
Moderator

Benutzerprofil
Anmeldungsdatum: 04.05.2001
Beiträge: 17736
Beitrag Shade Of Mine Moderator 16:11:07 18.03.2008   Titel:              Zitieren

Das Problem mit getter/setter ist wie mit goto. Zuviel verwenden ist furchtbar aber gleich garnicht verwenden ist mindestens genauso furchtbar.

Getter/Setter werden liebend gerne für alle internen Variablen genommen aber nur ein Bruchteil des internen States hat nach aussen zu gelangen (aber dieser Bruchteil muss nach aussen).

_________________
A language that doesn't affect the way you think about programming is not worth knowing.
Bashar
Mitglied

Benutzerprofil
Anmeldungsdatum: 15.05.2001
Beiträge: 16812
Beitrag Bashar Mitglied 16:36:48 18.03.2008   Titel:              Zitieren

Artchi schrieb:
Zitat:
Etwa so halt, wie Artchi das mit dem pModel bei MVC skizziert hatte; man hat ein Objekt und setzt ihm ein bestimmtes Objekt rein oder holt es heraus.

Und wie soll das Widget das Model kennen? Es geht dabei nicht darum, das Model zu verwalten, sondern nur zu kennen. Oder wie stellt ihr Verbindungen zu Objekten her?

Im Konstruktor.

_________________
OSL♥
Artchi
Autor

Benutzerprofil
Anmeldungsdatum: 16.03.2002
Beiträge: 8576
Beitrag Artchi Autor 17:05:17 18.03.2008   Titel:              Zitieren

Und wenn ich später ein anderes Model haben will? Denn eine View ist ja nicht für immer dazu verdammt ein und das selbe Model zu kennen. Ich will auch auf ein anderes Model zur Laufzeit umschalten können. Und jetzt?

Wie gesagt: bitte keine Ideal-Beispiele. Im Ctor kann ich natürlich alles erschlagen und den Anwender des Objektes massiv in der Handhabung zur Laufzeit des Objektes einschränken. Sprich: hast du einmal das Objekt erzeugt, darfs du nichts mehr damit machen/ändern. Ist das die Devise? :eek:

_________________
Bring back the Windows Start Menu Petition | GoPetition


Zuletzt bearbeitet von Artchi am 17:11:48 18.03.2008, insgesamt 4-mal bearbeitet
phlox81
Moderator

Benutzerprofil
Anmeldungsdatum: 21.04.2001
Beiträge: 7208
Beitrag phlox81 Moderator 17:31:04 18.03.2008   Titel:              Zitieren

Das heisst aber nicht das du ein SetModel(Model* m) benötigst:

C/C++ Code:
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
bool View::ChangeModel(int ModelID)
{
  Model* m = Controller::Instance().GetModel(ModelID);
  if(!m)
    return false;
  model = m;
  Update();
  return true;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
bool View::ChangeModel(int ModelID)
{
Model* m = Controller::Instance().GetModel(ModelID);
if(!m)
return false;
model = m;
Update();
return true;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
bool View::ChangeModel(int ModelID)
{
  Model* m = Controller::Instance().GetModel(ModelID);
  if(!m)
    return false;
  model = m;
  Update();
  return true;
}

_________________
Intelligenz ist eine Illusion des Menschen

phlox81.de | The Black Board | Code Node | Xing | Blog | Twitter
Artchi
Autor

Benutzerprofil
Anmeldungsdatum: 16.03.2002
Beiträge: 8576
Beitrag Artchi Autor 17:41:37 18.03.2008   Titel:              Zitieren

Das wird ja hier immer verrückter! :D Jetzt soll ich IDs hin und her schieben, wo doch ein Objekt selbst schon eine ID hat (die Adresse). Also alles doppelt gemoppelt verwalten? Macht das alles natürlich viel wartbarer. :o)

Neee, also lasst mal Leute. Das ist ja alles noch schlimmer als wenn ich es weiterhin so mache, wie bisher. Überzeugt hat mich das ganze nicht. Eher abgeschreckt. Bis auf das man vielleicht seine Methoden anders bennen könnte/sollte (anstatt setSize lieber resize usw.), habe ich aus der Diskussion nicht viel für mich neues gewinnen können.

Vielleicht haben andere etwas gewinnen können.

_________________
Bring back the Windows Start Menu Petition | GoPetition


Zuletzt bearbeitet von Artchi am 17:46:00 18.03.2008, insgesamt 4-mal bearbeitet
Bashar
Mitglied

Benutzerprofil
Anmeldungsdatum: 15.05.2001
Beiträge: 16812
Beitrag Bashar Mitglied 17:52:14 18.03.2008   Titel:              Zitieren

Artchi schrieb:
Und wenn ich später ein anderes Model haben will?

Dann brauchst du wohl zwangsläufig eine set-Methode. Die Frage ist: Brauchst du sie auch, wenn du später kein anderes Model haben willst?

_________________
OSL♥
Artchi
Autor

Benutzerprofil
Anmeldungsdatum: 16.03.2002
Beiträge: 8576
Beitrag Artchi Autor 17:55:24 18.03.2008   Titel:              Zitieren

Nein, dann natürlich nicht. Ich habe genug Klassen, wo z.B. etwas im Ctor übergeben wird, und es sich später nicht ändert. Aber das ist einfach meine pers. Designentscheidung für eine spezielle Klasse und nicht weil ich setter evil finde. Und mir geht es in diesem Thread eigentlich darum, das ich öffters im Forum lese das getter/setter evil sind, weil sie schlechtes Design sind. Also will ich eine Alternative wissen, und nicht einen speziellen Fall, weil der gerade ins Konzept passt. Und ich will keine Alternative wo ich Mehraufwand habe (siehe ID).

Denn ganz ehrlich? Ich habe mir Sorgen gemacht, das ich irgendwas verpasst habe. :D Deshalb auch die ernsthafte (!) Anfrage nach einem solchen Artikel.

_________________
Bring back the Windows Start Menu Petition | GoPetition


Zuletzt bearbeitet von Artchi am 18:03:29 18.03.2008, insgesamt 4-mal bearbeitet
Badestrand
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2006
Beiträge: 4342
Beitrag Badestrand Mitglied 18:03:31 18.03.2008   Titel:              Zitieren

Artchi schrieb:
Am Ende geht es hier anscheinend nur darum, wie die Funktion heißt? Soll heißen, die Anti-Setter-Getter-Fraktion stört sich nur am Funktionsnamen?
Nein, ist bei mir jedenfalls nicht so.

Beispiel MVC:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
class Widget : public IBlaObserver
{
public:
    Widget()
    {
        Model::addObserver( this );
    }

    ~Widget()
    {
        Model::removeOberserver( this );
    }
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Widget : public IBlaObserver
{
public:
Widget()
{
Model::addObserver( this );
}

~Widget()
{
Model::removeOberserver( this );
}
};
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Widget : public IBlaObserver
{
public:
    Widget()
    {
        Model::addObserver( this );
    }

    ~Widget()
    {
        Model::removeOberserver( this );
    }
};

Es kann sein, dass ich den Fall nur noch nicht hatte, aber wozu braucht man bei MVC ein wechselndes Modell? Oder wann würde es Sinn machen, dass verschiedene View-Elemente auf verschiedenen Modellen arbeiten? Und wenn ein Modell-Wechsel stattfindet, wieso sollte der Wechsel im View stattfinden und nicht im Modell oder einem Controller, der sich nach außen hin wie ein Modell gibt?

Ups, hatte den Beitrag vor ~2 Stunden angefangen, mir kam dann was dazwischen, wollte die Diskussion nicht wieder anheizen.


Zuletzt bearbeitet von Badestrand am 18:05:55 18.03.2008, insgesamt 1-mal bearbeitet
Artchi
Autor

Benutzerprofil
Anmeldungsdatum: 16.03.2002
Beiträge: 8576
Beitrag Artchi Autor 18:06:08 18.03.2008   Titel:              Zitieren

EDIT: Beitrag auf den es sich bezog ist out of date.

_________________
Bring back the Windows Start Menu Petition | GoPetition


Zuletzt bearbeitet von Artchi am 18:07:49 18.03.2008, insgesamt 1-mal bearbeitet
Apollon
Mitglied

Benutzerprofil
Anmeldungsdatum: 22.04.2003
Beiträge: 1879
Beitrag Apollon Mitglied 19:18:19 18.03.2008   Titel:              Zitieren

Knuddlbaer schrieb:
Apollon schrieb:
Knuddlbaer schrieb:
und wie kommt man an die nötigen Daten rann ?

Hoe? Man hat doch freien Zugriff drauf... Ach! Du meinst von aussen?! Nochmal: man reicht nicht Daten rum, sondern Objekte.


Davon das Du Deine Aussage wiederholst, wird sie nicht besser. Was fange ich mit einem Objekt an, das ich übergeben bekommen habe ?

Mit doofen Fragen wirst Du sie aber auch nicht schlechter machen.

Knuddlbaer schrieb:
Was bringt mir ein Objekt, das Berechnungen vornimmt wenn man die Daten nicht verwenden kann ?
Code:
var ErgebnissAnDemIchInteressiertBin = ObjektDasIchBekommenHabe.BerechneErgebnis(Parameter)
Code:
var ErgebnissAnDemIchInteressiertBin = ObjektDasIchBekommenHabe.BerechneErgebnis(Parameter)
Code:
var ErgebnissAnDemIchInteressiertBin = ObjektDasIchBekommenHabe.BerechneErgebnis(Parameter)

_________________
"Stil ist ein richtiges Weglassen des Unwesentlichen." - Anselm Feuerbach
Badestrand
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.08.2006
Beiträge: 4342
Beitrag Badestrand Mitglied 19:19:49 18.03.2008   Titel:              Zitieren

Wir könnten ja einige Präzendenzfälle zusammentragen (wie hier den MVC-Fall), wo dann im Artikel Alternativen aufgezeigt werden. Einen ganz allgemeinen Artikel zu schreiben, ist doch sicherlich ziemlich schwierig.
mathik
Mitglied

Benutzerprofil
Anmeldungsdatum: 26.12.2002
Beiträge: 256
Beitrag mathik Mitglied 00:28:48 18.05.2008   Titel:   Re: Klassen ohne getter/setter?            Zitieren

Artchi schrieb:
Also mich würde mal ein Artikel freuen, wie man denn Klassen-Designs ohne Getter und Setter hinbekommen soll. Lese hier immer wieder im Forum, das manche Leute es ein schlechtes Design finden. Aber mich würde mal interessieren, wie das ganze denn real umgesetzt werden sollte?

Wie würde man z.B. sowas "besser" lösen können:
C/C++ Code:
class Widget
{
    public:
       void setModel(Model);
       Model getModel();
};
C/C++ Code:
class Widget
{
public:
void setModel(Model);
Model getModel();
};
C/C++ Code:
class Widget
{
    public:
       void setModel(Model);
       Model getModel();
};


http://www.pragprog.com/articles/tell-dont-ask
isdochquatsch
Unregistrierter




Beitrag isdochquatsch Unregistrierter 09:57:05 18.05.2008   Titel:              Zitieren

Wenn ich einfach nur irgendwo ne Schriftgröße abfragen und ändern will, wie soll man den sowas ohne getter und setter machen?
Knuddlbaer
Mitglied

Benutzerprofil
Anmeldungsdatum: 11.12.2001
Beiträge: 5237
Beitrag Knuddlbaer Mitglied 10:43:35 18.05.2008   Titel:              Zitieren

Zitat:
Code:
var ErgebnissAnDemIchInteressiertBin = ObjektDasIchBekommenHabe.BerechneErgebnis(Parameter)
Code:
var ErgebnissAnDemIchInteressiertBin = ObjektDasIchBekommenHabe.BerechneErgebnis(Parameter)
Code:
var ErgebnissAnDemIchInteressiertBin = ObjektDasIchBekommenHabe.BerechneErgebnis(Parameter)


Hab ich da jetzt nicht wieder einen getter, der Daten zurückliefert ? Zumal reicht man jetzt doch wieder Daten rum (zumal Objekte ja auch an sich wieder Daten sind.)
exdre
Unregistrierter




Beitrag exdre Unregistrierter 22:58:48 04.10.2008   Titel:              Zitieren

Hi,

ich weiß, dass dieser Thread nun schon einige Zeit her ist, aber mich interessiert ganz speziell ein bestimmtes Problem:

Ich hab eine best. Klasse, sagen wir "sprite" (wie viele das aus der Spieleprogrammierung kennen). Dieses Dingen hat eine Position in Form eines Vektors (2D oder 3D ist eigtl egal, ich nehmn ma 3D): vector<float> pos; Aufgrund von OOP- und Kapselungsprinzipien kommt es für mich nicht in Frage pos public zu machen, heißt also "private: vector<float> pos;" Jetzt muss der Benutzer ja irgendwie Einfluss auf die Position haben. Da fallen mir folgende Möglichkeiten als Lösung ein, aber für jede auch direkt ein Gegenargument, deshalb bin ich z.Z. nicht sicher wie man das Problem lösen sollte:

1.
C/C++ Code:
class sprite
{
public:
     // standard getter/setter
     void setPos(const vector<float>& aPos);
     const vector<float>& getPos() const;
};
C/C++ Code:
class sprite
{
public:
// standard getter/setter
void setPos(const vector<float>& aPos);
const vector<float>& getPos() const;
};
C/C++ Code:
class sprite
{
public:
     // standard getter/setter
     void setPos(const vector<float>& aPos);
     const vector<float>& getPos() const;
};


2.
C/C++ Code:
class sprite
{
public:
     // andere Namen
     void move(const vector<float>& dir); // wobei man hier auch überlegen muss, ob move wirklich angebracht ist; denn move ist vom Namen her eher pos += dir statt pos = dir
     const vector<float>& where() const;
};
C/C++ Code:
class sprite
{
public:
// andere Namen
void move(const vector<float>& dir); // wobei man hier auch überlegen muss, ob move wirklich angebracht ist; denn move ist vom Namen her eher pos += dir statt pos = dir
const vector<float>& where() const;
};
C/C++ Code:
class sprite
{
public:
     // andere Namen
     void move(const vector<float>& dir); // wobei man hier auch überlegen muss, ob move wirklich angebracht ist; denn move ist vom Namen her eher pos += dir statt pos = dir
     const vector<float>& where() const;
};


3.
C/C++ Code:
class sprite
{
public:
     // setter als einfache Referenz
     vector<float>& pos();
     const vector<float>& pos() const;
};
C/C++ Code:
class sprite
{
public:
// setter als einfache Referenz
vector<float>& pos();
const vector<float>& pos() const;
};
C/C++ Code:
class sprite
{
public:
     // setter als einfache Referenz
     vector<float>& pos();
     const vector<float>& pos() const;
};


1. ist standard, warum das hier schwer ist komm ich gleich zu
2. ist "moderner" aber differenzierter (nähert sich eher dem konzept der c++ std.bibl.)
3. ist flexibel aber enthält im Grunde keine Kapselung mehr (abgesehen von der const-überladung) und Validation (weshalb viele setter statt direkten Zugriff benutzen) ist auch nicht mehr möglich.

So, weshalb die Methode 1 "schwer" ist:
  • Man übergibt setPos gleich einen neuen Vektor, der die alte Position überschreibt. Manchmal will man ein Objekt aber z.b. nur in y-Richtung verschieben und die alten x- und z-Werte beibehalten. Das würde dann in so einem "Monster" gipfeln:
    C/C++ Code:
    obj.setPos( obj.getPos().x, y, obj.getPos().z );
    C/C++ Code:
    obj.setPos( obj.getPos().x, y, obj.getPos().z );
    C/C++ Code:
    obj.setPos( obj.getPos().x, y, obj.getPos().z );
    das würde ich einem Kunden nicht gern zumuten.
  • Um dem zu umgehen könnte man entweder eine neue Methode einbauen, wie setPosY() die nur y-Werte setzt. Dabei würde die Klasse aber schließlich von set-Methoden überfüllt werden, die nur auf den Member pos zugreifen
    C/C++ Code:
    void setPos(const vector<float>& aPos);
    void setPosX(float aX);
    void setPosY(float aY);
    void setPosZ(float aZ);
    C/C++ Code:
    void setPos(const vector<float>& aPos);
    void setPosX(float aX);
    void setPosY(float aY);
    void setPosZ(float aZ);
    C/C++ Code:
    void setPos(const vector<float>& aPos);
    void setPosX(float aX);
    void setPosY(float aY);
    void setPosZ(float aZ);

  • Eine weitere Mögl. wäre, so etwas wie eine move-Methode einzubauen, dann könnte man für x- und z-Koordinate einfach 0 übergeben (s.O: move meint vom ausdruck her "bewegen", also eine Vektoraddition, sonst müsste man es "moveTo" nennen, wäre dann aber wieder das gleiche wie setPos). Möchte man dabei allerdings die absolute Koordinate bewegen, müsste man wieder eine Differenz aus alter und neuer Koordinate bilden:
    C/C++ Code:
    obj.move( 0, y - obj.getPos().y, 0 );
    C/C++ Code:
    obj.move( 0, y - obj.getPos().y, 0 );
    C/C++ Code:
    obj.move( 0, y - obj.getPos().y, 0 );

  • Ansonsten könnte man noch folgendermaßen argumentieren: Meine Klasse Vektor stellt sicherlich verschiedene Möglichkeiten bereit um die Position zu verschieben, ändern oder auch nur genau eine Koordinate zu verändern. Dann könnte man ja einfach eine Referenza auf pos zurückgeben, und den Benutzer mit den in vektor<> enthaltenen Funktionen arbeiten zu lassen. Das führt dann zu sowas wie
    C/C++ Code:
    obj.pos().y = y
    C/C++ Code:
    obj.pos().y = y
    C/C++ Code:
    obj.pos().y = y
    oder
    C/C++ Code:
    obj.pos().y += y
    C/C++ Code:
    obj.pos().y += y
    C/C++ Code:
    obj.pos().y += y
    etc., dies ist zwar flexibel und einfach, aber aus oben genannten Gründen für mich nicht möglich, da das ja einen Vollzugriff auf pos erlauben würde und dem Prinzip der Kapselung, der OOP und der Validation widerspricht (s.o.).


so, irgendwie zeigt sich da für mich keine "perfekte" Lösung. Das ganze mit dem Objekt sprite war nur ein Beispiel, würde man das abstrahieren käme man hierzu:

Wie erlaube ich möglichst nahe am Kapselungskonzept und an den Richtlinien der OOP in einer Klasse Zugriff auf ein Objekt, das in vielen (aber nicht allen) Eigenschaften/Wegen, die die Klasse dieses Objekts bereitstellt, manipuliert werden darf?


Ich hoffe ihr habt mein Problem verstanden, ich bin interessiert an allen möglichen Lösungsvorschlägen, wie ihr das in die Hand nehmen würdet (und warum ihr das so machen würdet).


Vielen Dank! :)

PS: ggf kann das Thema auch abgespalten werden
C/C++ Forum :: Allgemeines zum Magazin ::  Klassen ohne getter/setter?   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.