C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Frage zu Klassendesign

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Markus Zimmermann
Guest





PostPosted: Wed Mar 30, 2005 9:00 pm    Post subject: Frage zu Klassendesign Reply with quote



Hallo,
in Qt gibt es eine Klasse QDataTable. In dieser Klasse wird verkürzt
folgendes gemacht:

class QDataTable : public QTable
{
public:
//Reihe von Variablen
protected:
//Reihe von Variablen
private:
//Reihe von Variablen UND
QDataTablePrivate* d;
};

In der cpp-Datei wird dann vor den Implementierungen der Member-Funktionen
von QDataTable eine Klasse QDataTablePrivate definiert. Etwa so:

class QDataTablePrivate
{
public:
//Menge von Variablen (davon nur zwei Zeiger, keine Elementfunktionen)
};

Der Konstruktor von QDataTable ruft dann eine Funktion init() auf:

void QDataTable::init()
{
d = new QDataTablePrivate();
setAutoEdit( TRUE );
setSelectionMode( SingleRow );
setFocusStyle( FollowStyle );
d->trueTxt = tr( "True" );
d->falseTxt = tr( "False" );
d->datefmt = Qt::LocalDate;
reset();
connect( this, SIGNAL( selectionChanged() ),
SLOT( updateCurrentSelection()));
}

Was bringt die Vorgehensweise? Warum schreiben die Programmierer von
Trolltech die in QDataTablePrivate definierten Variablen nicht gleich in
den private-Bereich von QDataTable? Warum erzeugen Sie ein dynamisches
Objekt der QDataTablePrivate-Klasse?

Danke.Markus
--


--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Friedhelm Hoerner
Guest





PostPosted: Thu Mar 31, 2005 5:36 am    Post subject: Re: Frage zu Klassendesign Reply with quote



Markus Zimmermann <Markus.Zimmermann (AT) hz-bau (DOT) de> wrote

Quote:
Hallo,
in Qt gibt es eine Klasse QDataTable. In dieser Klasse wird verkürzt
folgendes gemacht:

class QDataTable : public QTable
{
public:
//Reihe von Variablen
protected:
//Reihe von Variablen
private:
//Reihe von Variablen UND
QDataTablePrivate* d;
};

In der cpp-Datei wird dann vor den Implementierungen der Member-Funktionen
von QDataTable eine Klasse QDataTablePrivate definiert. Etwa so:

class QDataTablePrivate
{
public:
//Menge von Variablen (davon nur zwei Zeiger, keine Elementfunktionen)
};

Der Konstruktor von QDataTable ruft dann eine Funktion init() auf:

void QDataTable::init()
{
d = new QDataTablePrivate();
[...]
}

Was bringt die Vorgehensweise? Warum schreiben die Programmierer von
Trolltech die in QDataTablePrivate definierten Variablen nicht gleich in
den private-Bereich von QDataTable? Warum erzeugen Sie ein dynamisches
Objekt der QDataTablePrivate-Klasse?

Das ist eine sogenannte "Compilation Firewall" auch unter dem
Stichwort "pimpl" = Pointer to Implementation bekannt. Damit wirken
sich Änderungen in der Implementierung (QDataTablePrivate) in keiner
Weise auf andere Quelltexte aus.
Im Headerfile (z.B.QDataTable.hpp) ändert sich garnichts, wenn sich in
der Implementierungsklasse etwas ändert (z.B neue Membervariablen
hinzugefügt oder entfernt werden). Und damit kann man das erneute
Compilieren aller Programme die QDataTable verwenden vermeiden.
Außerdem können Details der Implementierung komplett vor dem Nutzer
der Bibliothek versteckt werden.
Private member sind zwar dem Zugriff verborgen, nicht jedoch dem
Einblick;-)
Und das kann zum einen Implementierungsdetails verraten, und schafft
zum anderen eben unerwünschte Abhängigkeit beim Compilieren.

Gruss Friedhelm

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Rene Moehring
Guest





PostPosted: Thu Mar 31, 2005 7:00 am    Post subject: Re: Frage zu Klassendesign Reply with quote



On 30 Mar 2005 21:36:07 -0800, Friedhelm Hoerner wrote:
Quote:
Markus Zimmermann <Markus.Zimmermann (AT) hz-bau (DOT) de> wrote

[OT-Pimpl]

Das ist eine sogenannte "Compilation Firewall" auch unter dem
Stichwort "pimpl" = Pointer to Implementation bekannt. Damit wirken
sich Änderungen in der Implementierung (QDataTablePrivate) in keiner
Weise auf andere Quelltexte aus.
Im Headerfile (z.B.QDataTable.hpp) ändert sich garnichts, wenn sich in
der Implementierungsklasse etwas ändert (z.B neue Membervariablen
hinzugefügt oder entfernt werden). Und damit kann man das erneute
Compilieren aller Programme die QDataTable verwenden vermeiden.
Außerdem können Details der Implementierung komplett vor dem Nutzer
der Bibliothek versteckt werden.
Private member sind zwar dem Zugriff verborgen, nicht jedoch dem
Einblick;-)
Und das kann zum einen Implementierungsdetails verraten, und schafft
zum anderen eben unerwünschte Abhängigkeit beim Compilieren.

Sagt mal, ist es eigentlich günstiger den Pimpl so zu realisieren wie in
dem QT-Beispiel oder wäre es besser aus dem impl-struct ne komplette
Klasse zu machen, die die eigentlichen Memberfunktionen hat und zu denen
delegiert werden würde?
Beispiel:

A::foo()
{
pimpl_->foo();
}

--
I'm not a racist. I hate everyone equally!

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thorsten Nitz
Guest





PostPosted: Thu Mar 31, 2005 8:38 am    Post subject: Re: Frage zu Klassendesign Reply with quote

Rene Moehring schrieb:
Quote:
On 30 Mar 2005 21:36:07 -0800, Friedhelm Hoerner wrote:

Markus Zimmermann <Markus.Zimmermann (AT) hz-bau (DOT) de> wrote


[OT-Pimpl]

Obs wirklich OT ist? Ich halte es für ein C++-Idiom, das in anderen
Sprachen so nicht benutzt wird.

[hier: Implementierung ohne Memberfunktionen]


Quote:
Das ist eine sogenannte "Compilation Firewall" auch unter dem
Stichwort "pimpl" = Pointer to Implementation bekannt. Damit wirken
sich Änderungen in der Implementierung (QDataTablePrivate) in keiner
Weise auf andere Quelltexte aus.

Sagt mal, ist es eigentlich günstiger den Pimpl so zu realisieren wie in
dem QT-Beispiel oder wäre es besser aus dem impl-struct ne komplette
Klasse zu machen, die die eigentlichen Memberfunktionen hat und zu denen
delegiert werden würde?

Wenn Du an Interfaces glaubst, ist es günstig, in der außen sichtbaren
Klasse nur public-Elemente zu haben, mit Ausnahme des pimpl-Zeigers.

// A.h
class AImpl; // Vorwärtsdeklaration, gibt nichts über die Klasse preis

class A {
private:
AImpl *pimpl;
public:
// Ab hier öffentliche Schnittstelle
void foo();
A();
};

// A.cpp
A::A()
{ pimpl = new AImpl;
// weitere Initialisierungen
}

void A::foo()
{
pimpl->foo(); // reine Delegation
}

class AImpl {
// ... Hier passiert die eigentliche Arbeit
}

Hier habe ich Deinen Vorschlag der Delegation ebenfalls verwendet. Da
der Inhalt von A.cpp aber schon vor den Benutzern der Klasse A verborgen
ist, ist es nicht notwendig, dass AImpl die Schnittstelle von A eins zu
eins nachbaut. Die Methoden von A können also schon Algorithmen
enthalten, ohne dass die Kapselung verletzt wäre. Es bietet sich z.B.
an, in A schon Plausibilitätsprüfungen für Parameterwerte vorzunehmen,
oder Memberfunktionen zu implementieren, die auf der Basis anderer
öffentlicher Member implementiert werden können. Manche meinen
allerdings, es sei ein Designfehler, solche Funktionen überhaupt in die
Schnittstelle aufzunehmen.

Wesentlich ist, dass der Inhalt von A.h minimalistisch und stabil ist.

Tschö, wa!
Thorsten

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Mang
Guest





PostPosted: Thu Mar 31, 2005 9:17 am    Post subject: Re: Frage zu Klassendesign Reply with quote


"Thorsten Nitz" <T.Nitz (AT) epost (DOT) de> schrieb im Newsbeitrag
news:424bb707$1 (AT) news (DOT) ginko.net...
Quote:
Rene Moehring schrieb:

Wenn Du an Interfaces glaubst, ist es günstig, in der außen sichtbaren
Klasse nur public-Elemente zu haben, mit Ausnahme des pimpl-Zeigers.

// A.h
class AImpl; // Vorwärtsdeklaration, gibt nichts über die Klasse preis

class A {
private:
AImpl *pimpl;
public:
// Ab hier öffentliche Schnittstelle
void foo();
A();
};


Man kann die Vorwärtsdeklaration auch gleich in die private-Sektion von A
einbauen:
class A{
private:
class AImpl;
AImpl* pimpl;
};


Damit wird explizit ausgedrückt, wem AImpl gehört. Es kann auch einen
Unterschied bei tools wie Klassenbrowsern, Auto-Dokumentationen etc. machen,
ob andere AImpl dann überhaupt zu Gesicht bekommen.
Alternativ bietet sich auch ein Extranamespace (namespace impl{} etc.) an.

Ich finde beides sauberer, als die Deklaration einfach in den selben Raum zu
stellen wie die eigentliche zu benutzende Klasse


Thomas

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Rene Moehring
Guest





PostPosted: Thu Mar 31, 2005 1:30 pm    Post subject: Re: Frage zu Klassendesign Reply with quote

On Thu, 31 Mar 2005 10:38:02 +0200, Thorsten Nitz wrote:
Quote:
Rene Moehring schrieb:
On 30 Mar 2005 21:36:07 -0800, Friedhelm Hoerner wrote:

Markus Zimmermann <Markus.Zimmermann (AT) hz-bau (DOT) de> wrote


[OT-Pimpl]

Obs wirklich OT ist? Ich halte es für ein C++-Idiom, das in anderen
Sprachen so nicht benutzt wird.

[hier: Implementierung ohne Memberfunktionen]


Ich meinte eigentlich QT - war ein kleiner Vertipper.

Quote:

Das ist eine sogenannte "Compilation Firewall" auch unter dem
Stichwort "pimpl" = Pointer to Implementation bekannt. Damit wirken
sich Änderungen in der Implementierung (QDataTablePrivate) in keiner
Weise auf andere Quelltexte aus.

Sagt mal, ist es eigentlich günstiger den Pimpl so zu realisieren wie in
dem QT-Beispiel oder wäre es besser aus dem impl-struct ne komplette
Klasse zu machen, die die eigentlichen Memberfunktionen hat und zu denen
delegiert werden würde?

Wenn Du an Interfaces glaubst, ist es günstig, in der außen sichtbaren
Klasse nur public-Elemente zu haben, mit Ausnahme des pimpl-Zeigers.

// A.h
class AImpl; // Vorwärtsdeklaration, gibt nichts über die Klasse preis

class A {
private:
AImpl *pimpl;
public:
// Ab hier öffentliche Schnittstelle
void foo();
A();
};

// A.cpp
A::A()
{ pimpl = new AImpl;
// weitere Initialisierungen
}

void A::foo()
{
pimpl->foo(); // reine Delegation
}

class AImpl {
// ... Hier passiert die eigentliche Arbeit
}

Hier habe ich Deinen Vorschlag der Delegation ebenfalls verwendet. Da
der Inhalt von A.cpp aber schon vor den Benutzern der Klasse A verborgen
ist, ist es nicht notwendig, dass AImpl die Schnittstelle von A eins zu
eins nachbaut. Die Methoden von A können also schon Algorithmen
enthalten, ohne dass die Kapselung verletzt wäre. Es bietet sich z.B.
an, in A schon Plausibilitätsprüfungen für Parameterwerte vorzunehmen,
oder Memberfunktionen zu implementieren, die auf der Basis anderer
öffentlicher Member implementiert werden können. Manche meinen
allerdings, es sei ein Designfehler, solche Funktionen überhaupt in die
Schnittstelle aufzunehmen.

Wesentlich ist, dass der Inhalt von A.h minimalistisch und stabil ist.

Also ist es im Grunde egal.

--
I'm not a racist. I hate everyone equally!

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.