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 

Verzwickte Ableitungsgeschichte

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





PostPosted: Tue Jun 01, 2004 8:01 am    Post subject: Verzwickte Ableitungsgeschichte Reply with quote



Hi!

Ich möchte folgende Klassenhierarchie in C++ bauen:

ding1 ist ein Container, der ein Objekt myFoo der Klasse foo1 enthält.
ding2 ist ebenfalls ein Container, der ein Objekt myFoo der Klasse
foo2 enthält. foo1 und foo2 unterscheiden sich nur darin, dass foo2
Dateizugriffe enthält, also muss ich hier irgendwie einen Dateinamen
übergeben. Da foo1 und foo2 bis auf den Dateizugriff identisch sind
ist foo2 von foo1 abgeleitet. Allerdings unterscheiden sich die
Parameter der Konstruktoren, foo1(int hurz) und foo2(string filename,
int hurz) [bei Bedarf kann die Reihenfolge der Parameter auch geändert
werden].

ding1 und ding2 sind identisch bis auf das verwendete foo-Objekt. Ich
möchte nun ding2 von ding1 ableiten, so dass ich nur eine Klasse habe,
in der ich Änderungen vornehmen muss. Auch hier unterscheiden sich nur
die Konstruktor-Parameter: ding1(int hurz) und ding2(string filename,
int hurz).

Wenn ich nur straight-forward die Konstruktoren definiere, also

ding1(int hurz) : myFoo(hurz) {}
ding2(string filename, int hurz) : myFoo(filename, hurz) {}

schreibe, meckert der Compiler. Er möchte ding1() aufrufen, was ja
nicht existiert.

Wie kann ich dieses Problem lösen? Der Aufruf

ding2(string filename, int hurz) : ding1(hurz), myFoo(filename, hurz)

wird wohl nicht funktionieren, da durch ding1(hurz) schon ein
myFoo-Objekt erzeugt. Mit Zeigern könnte man dies umgehen, aber
eigentlich möchte ich keine Zeiger verwenden. Gibt es eine
Alternative?

Ciao,
Torsten

--
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
Karl Heinz Buchegger
Guest





PostPosted: Tue Jun 01, 2004 11:49 am    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote



Torsten Hensel wrote:
Quote:

Hi!

Ich möchte folgende Klassenhierarchie in C++ bauen:

ding1 ist ein Container, der ein Objekt myFoo der Klasse foo1 enthält.
ding2 ist ebenfalls ein Container, der ein Objekt myFoo der Klasse
foo2 enthält. foo1 und foo2 unterscheiden sich nur darin, dass foo2
Dateizugriffe enthält, also muss ich hier irgendwie einen Dateinamen
übergeben. Da foo1 und foo2 bis auf den Dateizugriff identisch sind
ist foo2 von foo1 abgeleitet. Allerdings unterscheiden sich die
Parameter der Konstruktoren, foo1(int hurz) und foo2(string filename,
int hurz) [bei Bedarf kann die Reihenfolge der Parameter auch geändert
werden].

ding1 und ding2 sind identisch bis auf das verwendete foo-Objekt. Ich
möchte nun ding2 von ding1 ableiten, so dass ich nur eine Klasse habe,
in der ich Änderungen vornehmen muss. Auch hier unterscheiden sich nur
die Konstruktor-Parameter: ding1(int hurz) und ding2(string filename,
int hurz).

Wenn ich nur straight-forward die Konstruktoren definiere, also

ding1(int hurz) : myFoo(hurz) {}
ding2(string filename, int hurz) : myFoo(filename, hurz) {}

schreibe, meckert der Compiler. Er möchte ding1() aufrufen, was ja
nicht existiert.

Wie kann ich dieses Problem lösen? Der Aufruf

ding2(string filename, int hurz) : ding1(hurz), myFoo(filename, hurz)


Irgendwie versteht einer von uns beiden die Sache nicht so ganz.

Wenn ich nochmal zusammenfasse

class ding1
{
...

foo1 myFoo;
};

class ding2 : public ding1
{
...

foo2 myFoo;
}


Wenn Du dann ein Objekt erzeugst:

ding2 DasDing;

dann hat DasDing genau 2 myFoo Member! Eines vom Typ foo1 und eines vom
Typ foo2. Klar musst Du beide initialisieren.

Quote:
wird wohl nicht funktionieren, da durch ding1(hurz) schon ein
myFoo-Objekt erzeugt.

Nicht der Konstruktor Aufruf erzeugt die Member! Die Member sind schon da,
durch den Konstruktor werden sie lediglich initialisiert.

Quote:
Mit Zeigern könnte man dies umgehen, aber
eigentlich möchte ich keine Zeiger verwenden. Gibt es eine
Alternative?

Ich denke mal, dass die Art und Weise wie Du die Ableitung betreibst
unsinnig ist. Da Du 'seltsame' Namen verwendet hast, ist es leider
schwierig zu entscheiden was Du eigentlich erreichen moechtest.
Ich koennte mir aber vorstellen, dass eine gemeinsame Basisklasse
von ding1 und ding2 eigentlich das darstellt, was Du machen moechtest:

class ding
{
// alles was ding1 und ding2 geimeinsam haben
};

class ding1: public ding
{
// speziell fuer ding1 Funktionalitaet
};

class ding2: public ding
{
// speziell fuer ding2 Funktionalitaet
};

Du verlagerst die geimeinsame Funktionalitaet nach ding aus. Lediglich
die unterschiedlichen Teile werden einmal in ding1 und zum anderen in
ding2 gebracht. Falls ich falsch liege poste doch noch mal mit etwas
besseren Klassen und Member-Namen, damit man sich darunter auch
was vorstellen kann. Bei einem Hierarchie-Aufsatz gibt es viele
Moeglichkeiten und manchmal hat man sich so verlaufen, dass man selbst
nicht erkennt dass es besser ist die Hierarchie ueber Bord zu schmeissen,
als auf biegen und brechen die Hierarchie so hin zu trimmen, dass sie
funktioniert.

--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

--
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
Andreas Huennebeck
Guest





PostPosted: Tue Jun 01, 2004 12:20 pm    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote



Torsten Hensel wrote:

Quote:
Ich möchte folgende Klassenhierarchie in C++ bauen:

ding1 ist ein Container, der ein Objekt myFoo der Klasse foo1 enthält.
ding2 ist ebenfalls ein Container, der ein Objekt myFoo der Klasse
foo2 enthält. foo1 und foo2 unterscheiden sich nur darin, dass foo2
Dateizugriffe enthält, also muss ich hier irgendwie einen Dateinamen
übergeben. Da foo1 und foo2 bis auf den Dateizugriff identisch sind
ist foo2 von foo1 abgeleitet. Allerdings unterscheiden sich die
Parameter der Konstruktoren, foo1(int hurz) und foo2(string filename,
int hurz) [bei Bedarf kann die Reihenfolge der Parameter auch geändert
werden].

ding1 und ding2 sind identisch bis auf das verwendete foo-Objekt. Ich
möchte nun ding2 von ding1 ableiten, so dass ich nur eine Klasse habe,
in der ich Änderungen vornehmen muss. Auch hier unterscheiden sich nur
die Konstruktor-Parameter: ding1(int hurz) und ding2(string filename,
int hurz).

Ein Weg waere, dass Du nur ein ding Objekt erzeugst, welches einen
Pointer auf ein foo-Objekt enthaelt. ding bekommt zwei Konstruktoren:

ding(int hurz) : myFoo(new foo1(hurz)) {}
ding(string filename, int hurz) : myFoo(new foo2(filename, hurz)) {}

foo1 und foo2 sind von foo abgeleitet, welches das gemeinsame Interface
deklariert.

Tschau
Andreas
--
Andreas Hünnebeck | email: [email]ah (AT) despammed (DOT) com[/email]
----- privat ---- | www : http://www.huennebeck-online.de
Fax/Anrufbeantworter: 0721/151-284301 o. 0180/50525-5232659 (24 Pfg/Min)
SMS: D1=72617 D2=0172/7366-042 E-Plus=0177/7934-396 Viag=0179/2029-894
GPG-Key: http://www.huennebeck-online.de/public_keys/andreas.asc

--
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
Torsten Hensel
Guest





PostPosted: Wed Jun 02, 2004 7:16 am    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote

Karl Heinz Buchegger wrote:
Quote:
Irgendwie versteht einer von uns beiden die Sache nicht so ganz.

Das habe ich befürchtet ;-)

Quote:
Wenn ich nochmal zusammenfasse

class ding1
{
...

foo1 myFoo;
};

class ding2 : public ding1
{
...

foo2 myFoo;
}

Fast. Es fehlt noch: class foo1... und class foo2 : public foo1

Quote:
Wenn Du dann ein Objekt erzeugst:

ding2 DasDing;

dann hat DasDing genau 2 myFoo Member! Eines vom Typ foo1 und eines vom
Typ foo2. Klar musst Du beide initialisieren.

Yuck! Und genau das möchte ich eben nicht. Ich wollte myFoo überladen,
so dann ding1 ein Objekt der Klasse foo1 und ding2 nur ein Objekt der
Klasse foo2 enthält.

Quote:
Ich denke mal, dass die Art und Weise wie Du die Ableitung betreibst
unsinnig ist. Da Du 'seltsame' Namen verwendet hast, ist es leider
schwierig zu entscheiden was Du eigentlich erreichen moechtest.
Ich koennte mir aber vorstellen, dass eine gemeinsame Basisklasse
von ding1 und ding2 eigentlich das darstellt, was Du machen moechtest:

Ok, andere Namen: Ich habe eine Containerklasse CContainer. Diese
enthält Objekte von verschiedenen Hilfsklassen und (bis auf den
Konstruktor, der diese Objekte initialisiert) ansonsten keine weitere
Funktionalität.

CContainer enthält ein Objekt myMedian der Klasse CMedianList, die zum
Speichern von mehreren Median-Werten (und einer Reihe anderer Werte
zur Berechnung) sowie zur Durchführung verschiedener Berechnungen
dient.

Nun habe ich noch eine zweite Klasse CContainerSave. Diese Klasse ist
fast identisch zu CContainer. Der einzige Unterschied ist, dass diese
Klasse ein Objekt myMedian vom Typ CMedianSave enthält. CMedianSave
ist von CMedian abgeleitet. Diese Klasse enthält zusätzlich ein Objekt
der Klasse CFileIO, das Dateizugriffe ermöglicht.

Das Ziel ist folgendes: Ich erzeuge ein Objekt der Klasse CContainer
und füge mehrere Median-Werte zu CContainer::myMedian. Sind genügend
Werte vorhanden kann ich damit verschiedene Berechnungen durchführen.

Wenn ich ein Objekt der Klasse CContainerSave erzeuge soll eine Datei
erzeugt und zum Schreiben geöffnet werden. Auch hier werden
verschiedene Median-Werte hinzugefügt und Berechnungen durchgeführt.
Schließlich brauche ich eine weitere Funktion, die aus den in myMedian
intern gespeicherten Werte weitere Dinge berechnet und die Ergebnisse
in der Datei abspeichert. Im Destruktor von CContainerSave wird die
Datei geschlossen.

Quote:
Bei einem Hierarchie-Aufsatz gibt es viele
Moeglichkeiten und manchmal hat man sich so verlaufen, dass man selbst
nicht erkennt dass es besser ist die Hierarchie ueber Bord zu schmeissen,
als auf biegen und brechen die Hierarchie so hin zu trimmen, dass sie
funktioniert.

Und genau deshalb frage ich zuerst hier nach, bevor ich mich verrenne,
dann etwas hinbastle und dann später feststelle, dass das alles
totaler Blödsinn war.

Ciao,
Torsten

--
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
Karl Heinz Buchegger
Guest





PostPosted: Wed Jun 02, 2004 9:50 am    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote

Torsten Hensel wrote:
Quote:

Karl Heinz Buchegger wrote:
Irgendwie versteht einer von uns beiden die Sache nicht so ganz.

Das habe ich befürchtet ;-)

Wenn ich nochmal zusammenfasse

class ding1
{
...

foo1 myFoo;
};

class ding2 : public ding1
{
...

foo2 myFoo;
}

Fast. Es fehlt noch: class foo1... und class foo2 : public foo1

Wenn Du dann ein Objekt erzeugst:

ding2 DasDing;

dann hat DasDing genau 2 myFoo Member! Eines vom Typ foo1 und eines vom
Typ foo2. Klar musst Du beide initialisieren.

Yuck! Und genau das möchte ich eben nicht. Ich wollte myFoo überladen,
so dann ding1 ein Objekt der Klasse foo1 und ding2 nur ein Objekt der
Klasse foo2 enthält.

Dann darfst Du ding2 nicht von ding1 ableiten.

Quote:

Ich denke mal, dass die Art und Weise wie Du die Ableitung betreibst
unsinnig ist. Da Du 'seltsame' Namen verwendet hast, ist es leider
schwierig zu entscheiden was Du eigentlich erreichen moechtest.
Ich koennte mir aber vorstellen, dass eine gemeinsame Basisklasse
von ding1 und ding2 eigentlich das darstellt, was Du machen moechtest:

Ok, andere Namen: Ich habe eine Containerklasse CContainer. Diese
enthält Objekte von verschiedenen Hilfsklassen und (bis auf den
Konstruktor, der diese Objekte initialisiert) ansonsten keine weitere
Funktionalität.

CContainer enthält ein Objekt myMedian der Klasse CMedianList, die zum
Speichern von mehreren Median-Werten (und einer Reihe anderer Werte
zur Berechnung) sowie zur Durchführung verschiedener Berechnungen
dient.

Nun habe ich noch eine zweite Klasse CContainerSave. Diese Klasse ist
fast identisch zu CContainer. Der einzige Unterschied ist, dass diese
Klasse ein Objekt myMedian vom Typ CMedianSave enthält. CMedianSave
ist von CMedian abgeleitet. Diese Klasse enthält zusätzlich ein Objekt
der Klasse CFileIO, das Dateizugriffe ermöglicht.

Das Ziel ist folgendes: Ich erzeuge ein Objekt der Klasse CContainer
und füge mehrere Median-Werte zu CContainer::myMedian. Sind genügend
Werte vorhanden kann ich damit verschiedene Berechnungen durchführen.

Wenn ich ein Objekt der Klasse CContainerSave erzeuge soll eine Datei
erzeugt und zum Schreiben geöffnet werden. Auch hier werden
verschiedene Median-Werte hinzugefügt und Berechnungen durchgeführt.
Schließlich brauche ich eine weitere Funktion, die aus den in myMedian
intern gespeicherten Werte weitere Dinge berechnet und die Ergebnisse
in der Datei abspeichert. Im Destruktor von CContainerSave wird die
Datei geschlossen.

OK. Wenn ich jetzt richtig verstanden habe, dann moechtest Du CContainerSave
von CContainer ableiten, da ja anzunehmenderweise einiges an Funktionalitaet
von CContainer auch in CContainerSave gebraucht werden kann. Du moechtest
allerdings den CMedian in CContainer durch einen CMedianSave ersetzen.


class CContainerBase
{
.....
}

class CContainer : public CContainerBase
{
..
CMedian myMedian;
};

class CContainerSave : public CContainerBase
{
..
CMedianSave myMedian;
};

In CContainerBase lagerst Du alles rein, was sowohl in CContainer
als auch in CContainerSave verfuegbar sein soll.

Ich bin mir allerdings noch nicht sicher ob ich das so machen wuerde.
Ich wuerde wahrscheinlich auf CContainerSave und CMedianSave komplett
verzichten und stattdessen eine eigenstaendige Klasse bauen, die ein
CContainer Objekt speichern kann. So was wie ein stream Objekt. Wenn
ich dem einen CContainer hineinstopfe, macht er die Berechnungen mit
dem CContainer und speichert sie auf ein File.

Quote:

Bei einem Hierarchie-Aufsatz gibt es viele
Moeglichkeiten und manchmal hat man sich so verlaufen, dass man selbst
nicht erkennt dass es besser ist die Hierarchie ueber Bord zu schmeissen,
als auf biegen und brechen die Hierarchie so hin zu trimmen, dass sie
funktioniert.

Und genau deshalb frage ich zuerst hier nach, bevor ich mich verrenne,
dann etwas hinbastle und dann später feststelle, dass das alles
totaler Blödsinn war.

Ob's Blödsinn war stellt sich oft erst nach geraumer Zeit heraus :-)

--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

--
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
Torsten Hensel
Guest





PostPosted: Wed Jun 02, 2004 2:03 pm    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote

Karl Heinz Buchegger <kbuchegg (AT) gascad (DOT) at> wrote:
Quote:
Ich wollte myFoo überladen, so dann ding1 ein Objekt der Klasse foo1 und
ding2 nur ein Objekt der Klasse foo2 enthält.
Dann darfst Du ding2 nicht von ding1 ableiten.

Ok, genau so habe ich es im Moment auch gemacht.

Quote:
OK. Wenn ich jetzt richtig verstanden habe, dann moechtest Du CContainerSave
von CContainer ableiten, da ja anzunehmenderweise einiges an Funktionalitaet
von CContainer auch in CContainerSave gebraucht werden kann. Du moechtest
allerdings den CMedian in CContainer durch einen CMedianSave ersetzen.

Exakt.

Quote:
class CContainerBase
{
.....
}

class CContainer : public CContainerBase
{
..
CMedian myMedian;
};

class CContainerSave : public CContainerBase
{
..
CMedianSave myMedian;
};

In CContainerBase lagerst Du alles rein, was sowohl in CContainer
als auch in CContainerSave verfuegbar sein soll.

Das wäre eine Möglichkeit, die mir jetzt auch naheliegend erscheint,
auf die ich bisher aber nicht gekommen bin.

Quote:
Ich bin mir allerdings noch nicht sicher ob ich das so machen wuerde.
Ich wuerde wahrscheinlich auf CContainerSave und CMedianSave komplett
verzichten und stattdessen eine eigenstaendige Klasse bauen, die ein
CContainer Objekt speichern kann. So was wie ein stream Objekt. Wenn
ich dem einen CContainer hineinstopfe, macht er die Berechnungen mit
dem CContainer und speichert sie auf ein File.

Selbst Streams zu programmieren habe ich noch nie gemacht. Wie würde
denn sowas (oder was ähnliches, einfacheres) aussehen?

Spontan fällt mir dazu nur meine Klasse fileIO ein:

class fileIO {
public: // some file io stuff
void SaveIt(const CMedian& toSave);
};

Aber dann kann ich in SaveIt nur auf public Member von toSave
zugreifen - und dafür brauche ich zu viele, um für alle
Zugriffsfunktionen schreiben zu müssen. Oder muss ich die Klasse
fileIO oder die Funktion SaveIt als friend deklarieren?

class CMedian {
friend class fileIO; //...
}

Ciao,
Torsten

--
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
Karl Heinz Buchegger
Guest





PostPosted: Wed Jun 02, 2004 3:30 pm    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote

Torsten Hensel wrote:
Quote:

Ich bin mir allerdings noch nicht sicher ob ich das so machen wuerde.
Ich wuerde wahrscheinlich auf CContainerSave und CMedianSave komplett
verzichten und stattdessen eine eigenstaendige Klasse bauen, die ein
CContainer Objekt speichern kann. So was wie ein stream Objekt. Wenn
ich dem einen CContainer hineinstopfe, macht er die Berechnungen mit
dem CContainer und speichert sie auf ein File.

Selbst Streams zu programmieren habe ich noch nie gemacht.

Nimm das 'stream' hier nicht zu woertlich, hat nichts mit C++
streams zu tun (Koennte man aber machen. Hmm. Waere gar nicht
das schlimmste: operator << als freistehende Funktion implementieren
und ab geht die Luzy).

Quote:
Wie würde
denn sowas (oder was ähnliches, einfacheres) aussehen?

Spontan fällt mir dazu nur meine Klasse fileIO ein:

class fileIO {
public: // some file io stuff
void SaveIt(const CMedian& toSave);
};

Aber dann kann ich in SaveIt nur auf public Member von toSave
zugreifen - und dafür brauche ich zu viele, um für alle
Zugriffsfunktionen schreiben zu müssen.

Nun. Du kannst ja der Klasse Median Methoden spendieren die
auf das File schreiben. Ist mir ueberhaupt ziemlich unklar
warum Du das nicht machst, sondern statt dessen eine
2.te Klasse in dein System einziehst. Dein EXE wird
deswegen auch nicht kleiner und ein CMedian Objekt wird
auch nicht groesser, nur weil Du ihm ein paar zusaetzliche
Funktionen verpasst.

Quote:
Oder muss ich die Klasse
fileIO oder die Funktion SaveIt als friend deklarieren?

class CMedian {
friend class fileIO; //...
}

Kannst natuerlich auch machen.

Warum nicht einfach:

class CMedian {
public:

bool WriteTo( fileIO& out ) const;
};

Dann erhebt sich allerdings die Frage warum es ausgerechnet
ein fileIO Objekt sein muss (was auch immer fileIO macht).
Warum nicht einfach das was dir C++ sowieso zur Verfuegung stellt:

class CMedian {
public:

ostream& WriteTo( ostream& out ) const;
};

--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

--
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
Torsten Hensel
Guest





PostPosted: Thu Jun 03, 2004 8:15 am    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote

Karl Heinz Buchegger <kbuchegg (AT) gascad (DOT) at> wrote:
Quote:
Nun. Du kannst ja der Klasse Median Methoden spendieren die
auf das File schreiben. Ist mir ueberhaupt ziemlich unklar
warum Du das nicht machst, sondern statt dessen eine
2.te Klasse in dein System einziehst.

Weil ich nicht einfach in eine Text-Datei speichere, sondern eine
Bibliothek (CodeBase) benutze, um DBF-Dateien zu erzeugen.

Quote:
Dein EXE wird
deswegen auch nicht kleiner und ein CMedian Objekt wird
auch nicht groesser, nur weil Du ihm ein paar zusaetzliche
Funktionen verpasst.

Das wäre mir egal - nur vom der Logik her passt Speichern nicht zu
CMedian. Es werden ja nicht die Werte der Member von CMedian
gespeichert, sondern mithilfe der Member werden eine Reihe von
temporären Werten berechnet, und diese abgespeichert.

Quote:
Oder muss ich die Klasse
fileIO oder die Funktion SaveIt als friend deklarieren?
Kannst natuerlich auch machen.

Spricht da was dagegen? Irgendwie wirkt das auf mich unsauber, weil
ich so die Kapselung der Klasse CMedian aufweiche...

Quote:
Warum nicht einfach:

class CMedian {
public:

bool WriteTo( fileIO& out ) const;
};

Dann erhebt sich allerdings die Frage warum es ausgerechnet
ein fileIO Objekt sein muss (was auch immer fileIO macht).

FileIO erzeugt die Ausgabedatei im Kostruktor und kümmert sich um das
Fehler-Handling.

Quote:
Warum nicht einfach das was dir C++ sowieso zur Verfuegung stellt:

class CMedian {
public:

ostream& WriteTo( ostream& out ) const;
};

Dann müsste ich eher von ostream ableiten, oder einen eigenen Stream
(DBF_ostream) programmieren. Also doch eher die schon vorhandene
Klasse fileIO.

Ciao,
Torsten

--
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
Torsten Hensel
Guest





PostPosted: Thu Jun 03, 2004 11:00 am    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote

Hi!

Ich hatte eben eine Eingebung, ich versuche, sie mal in Worte zu
fassen.

Karl Heinz Buchegger <kbuchegg (AT) gascad (DOT) at> wrote:
Quote:
Nun. Du kannst ja der Klasse Median Methoden spendieren die
auf das File schreiben.

Das wäre nach meinem jetzigen Kenntnisstand die beste Lösung, denn ich
habe keine simple Save-Funktion die nur eine Reihe von Werte
abspeichert, meine Funktion ist etwas komplizierter:

Zunächst werden mit einem Member-Array von CMedian temporäre Werte
berechnet, die später zum Speichern bzw. für weitere Berechnungen
verwendet werden. Dann werden die benutzten Member auf 0 gesetzt. Nun
kommt die eigentliche Berechnung. In einer while-Schleife wird die
Member-Liste von CMedian geleert, die entfernten Elemente analysiert
und mit deren Werte weitere temporäre Werte berechnet, von denen
einige schließlich abgespeichert werden.

Diese Funktion benötige ich jedoch nur, wenn auch tatsächlich
gespeichert werden soll. Für den Fall, dass ich das Speichern nicht
brauche reduziert sich die Funktion auf "setze alle Member auf 0 bzw.
leere die Liste".

Nun könnte ich das ganze folgendermaßen angehen: Die Basisklasse
bekommt eine Funktion Reinit(), die alle Member auf 0 setzt und die
Liste leert. Die davon abgeleitete Klasse bekommt eine andere Funktion
(ob überladen oder nicht ist egal), in der zuerst die benötigten Werte
berechnet und gespeichert werden, danach wird die Funktion Reinit()
der Basisklasse aufgerufen.

Für diesen Ansatz bräuchte ich doch die Vererbungshierarchie, die ich
ursprünglich haben wollte - allerdings werde ich wohl die
Container-Klasse weglassen: CMedian ist die Basisklasse, CMedianSave
enthält zusätzlich noch Funktionalität zum Speichern. Ob dies in einer
Separaten Klasse oder in CMedianSave direkt implementiert ist spielt
eigentlich keine Rolle. Persönlich finde ich es schöner, wenn der
Dateizugriff gekapselt ist. Dann muss ich jedoch diese 16 Werte der
Berechnungsfunktion an die Speicherfunktion übergeben - nicht gerade
eine schöne Funktionsdefinition.

Dadurch dass CMedianSave durch die Vererbung kaum was enthält würde es
sich doch anbieten, die Dateizugriffsroutinen direkt in diese Klasse
zu packen. Schließlich ist das der einzige Unterschied zwischen den
beiden Klassen.

Any comments?

Ciao,
Torsten

--
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
Karl Heinz Buchegger
Guest





PostPosted: Thu Jun 03, 2004 12:01 pm    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote

Torsten Hensel wrote:
Quote:

Karl Heinz Buchegger <kbuchegg (AT) gascad (DOT) at> wrote:
Nun. Du kannst ja der Klasse Median Methoden spendieren die
auf das File schreiben. Ist mir ueberhaupt ziemlich unklar
warum Du das nicht machst, sondern statt dessen eine
2.te Klasse in dein System einziehst.

Weil ich nicht einfach in eine Text-Datei speichere, sondern eine
Bibliothek (CodeBase) benutze, um DBF-Dateien zu erzeugen.

OK. Und Du willst die Klasse auch ohne den DBF Support einsetzen koennen.
Ist ein Grund.

Quote:

Dein EXE wird
deswegen auch nicht kleiner und ein CMedian Objekt wird
auch nicht groesser, nur weil Du ihm ein paar zusaetzliche
Funktionen verpasst.

Das wäre mir egal - nur vom der Logik her passt Speichern nicht zu
CMedian. Es werden ja nicht die Werte der Member von CMedian
gespeichert, sondern mithilfe der Member werden eine Reihe von
temporären Werten berechnet, und diese abgespeichert.

Dann wuerde ich das auch so machen.
Kapsle diese berechneten Werte in eine eigene Klasse (CResult
oder so aehnlich) und lass Dir von CMedian so ein Objekt
auf Anforderung geben. In einer anderen Funktion (die muss
ja nicht unbedingt in einer Klasse beheimatet sein), schreibst
Du dann die Ergebnisse in die DBF Datei.
Und schwups: CMedian weiss gar nichts mehr davon, dass das
irgendwie auf eine Datei kommt. Es berechnet Werte. Was mit
den Werten weiter geschieht ist CMedian vollkommen schnurz.

In anderen Worten: trenne das Dateihandling komplett von CMedian
ab. Ist auch irgendwie logisch. Ein CMedian Objekt weis wie man
statistische Werte berechnet. Aber warum soll das Ding ueber
einen DBF Aufbau Bescheid wissen. Das ist doch nicht seine
Aufgabe.

Quote:
Warum nicht einfach das was dir C++ sowieso zur Verfuegung stellt:

class CMedian {
public:

ostream& WriteTo( ostream& out ) const;
};

Dann müsste ich eher von ostream ableiten, oder einen eigenen Stream
(DBF_ostream) programmieren. Also doch eher die schon vorhandene
Klasse fileIO.

Zum Zeitpunkt als ich das geschrieben habe, wusste ich noch
nichts von DBF Smile So wie Du DBF in eine Klasse kapselst ist
das schon ok.

--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

--
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
Torsten Hensel
Guest





PostPosted: Fri Jun 04, 2004 6:59 am    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote

Andreas Huennebeck wrote:
Quote:
Ein Weg waere, dass Du nur ein ding Objekt erzeugst, welches einen
Pointer auf ein foo-Objekt enthaelt. ding bekommt zwei Konstruktoren:

Zeiger sind mir sehr unsympatisch!

Quote:
ding(int hurz) : myFoo(new foo1(hurz)) {}
ding(string filename, int hurz) : myFoo(new foo2(filename, hurz)) {}

foo1 und foo2 sind von foo abgeleitet, welches das gemeinsame Interface
deklariert.

Ich muss dann natürlich im Destruktor den Zeiger myFoo wieder
freigeben.

Was passiert in dem Fall, wenn im Konstruktor etwas schief läuft? Wie
kann ich das sicher abfangen? Wird dann dennoch der Destruktor
aufgerufen, oder muss ich den Speicher von Hand oder mit Exceptions
wieder freigeben? Das sind alles Dinge, über die ich mir ohne Zeiger
keine Gedanken machen muss. Ok, bei einem guten Compiler (???) wird
der Speicher bei Programmende dann sowieso wieder freigegeben, aber
sauber ist das nicht!

Ciao,
Torsten

--
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
Torsten Hensel
Guest





PostPosted: Fri Jun 04, 2004 7:15 am    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote

Karl Heinz Buchegger <kbuchegg (AT) gascad (DOT) at> wrote:
Quote:
Das wäre mir egal - nur vom der Logik her passt Speichern nicht zu
CMedian. Es werden ja nicht die Werte der Member von CMedian
gespeichert, sondern mithilfe der Member werden eine Reihe von
temporären Werten berechnet, und diese abgespeichert.
Kapsle diese berechneten Werte in eine eigene Klasse (CResult
oder so aehnlich) und lass Dir von CMedian so ein Objekt
auf Anforderung geben. In einer anderen Funktion (die muss
ja nicht unbedingt in einer Klasse beheimatet sein), schreibst
Du dann die Ergebnisse in die DBF Datei.

Das war auch eine meiner ersten Ideen. Irgendwie bin ich dann doch
wieder davon abgekommen.

Quote:
In anderen Worten: trenne das Dateihandling komplett von CMedian
ab. Ist auch irgendwie logisch. Ein CMedian Objekt weis wie man
statistische Werte berechnet. Aber warum soll das Ding ueber
einen DBF Aufbau Bescheid wissen. Das ist doch nicht seine
Aufgabe.

Hier ist jedoch das Problem, dass ich die Berechnung der Werte nur
dann brauche, wenn ich sie auch speichern will. Brauche ich keinen
Dateizugriff, so muss ich die Werte auch nicht berechnen. Die Funktion
muss ich (wahrscheinlich?) dennoch aufrufen - also brauche ich doch
zwei verschiedene Varianten der Berechnungsfunktion.

Habe ich nicht irgendwann mal geschrieben wie die Funktion in etwa
aussieht? Zunächst werden mit Hilfe von Membervariablen temporäre
Werte berechnet, danach diese Member auf 0 gesetzt. Als nächstes wird
eine Member-Liste nach und nach geleert und mit den Werten aus der
Liste erneut etwas berechnet. Im Endeffekt sind nach dieser Funktion
eine Reihe von Membern 0 und die Liste ist leer - und genau das
brauche ich wahrscheinlich auch bei der Variante ohne Dateizugriff.

Ciao,
Torsten

--
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
Karl Heinz Buchegger
Guest





PostPosted: Fri Jun 04, 2004 8:25 am    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote

Torsten Hensel wrote:
Quote:


In anderen Worten: trenne das Dateihandling komplett von CMedian
ab. Ist auch irgendwie logisch. Ein CMedian Objekt weis wie man
statistische Werte berechnet. Aber warum soll das Ding ueber
einen DBF Aufbau Bescheid wissen. Das ist doch nicht seine
Aufgabe.

Hier ist jedoch das Problem, dass ich die Berechnung der Werte nur
dann brauche, wenn ich sie auch speichern will. Brauche ich keinen
Dateizugriff, so muss ich die Werte auch nicht berechnen. Die Funktion
muss ich (wahrscheinlich?) dennoch aufrufen - also brauche ich doch
zwei verschiedene Varianten der Berechnungsfunktion.

Ah - ja.
Das klingt fuer mich allerdings nach: Die Funktion macht zuviel.
Ich wuerde versuchen, den Teil 'ohne Speichern' auf Biegen und
Brechen als 2.-ten Teil der Variante 'mit Speichern' hinzukriegen.
Willst Du Speichern, dann sind halt 2 Aufrufe erforderlich. Willst
Du nicht Speichern entfaellt der erste.

Quote:

Habe ich nicht irgendwann mal geschrieben wie die Funktion in etwa
aussieht?

Doch. Ich erinnere mich. Es ist schwer Code zu verfolgen von dem
man nur eine Beschreibung hat. Tschuldigung.

Quote:
Zunächst werden mit Hilfe von Membervariablen temporäre
Werte berechnet, danach diese Member auf 0 gesetzt. Als nächstes wird
eine Member-Liste nach und nach geleert und mit den Werten aus der
Liste erneut etwas berechnet. Im Endeffekt sind nach dieser Funktion
eine Reihe von Membern 0 und die Liste ist leer - und genau das
brauche ich wahrscheinlich auch bei der Variante ohne Dateizugriff.


Ganz ehrlich: Ich denke wir sind an einem Punkt angelangt, an dem
ich nur mehr noch mehr Verwirrung stifte. Ich hoffe ich konnte
Dir einige Ideen geben, was man alles machen koennte.

--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

--
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
Torsten Hensel
Guest





PostPosted: Wed Jun 09, 2004 8:40 am    Post subject: Re: Verzwickte Ableitungsgeschichte Reply with quote

Karl Heinz Buchegger wrote:
Quote:
Hier ist jedoch das Problem, dass ich die Berechnung der Werte nur
dann brauche, wenn ich sie auch speichern will. Brauche ich keinen
Dateizugriff, so muss ich die Werte auch nicht berechnen. Die Funktion
muss ich (wahrscheinlich?) dennoch aufrufen - also brauche ich doch
zwei verschiedene Varianten der Berechnungsfunktion.

Ok, ich hatte endlich mal die Gelegenheit, dies genauer nachzuschauen.
Ich brauche diese Funktion wirklich nur, wenn ich auch speichern will.

Quote:
Das klingt fuer mich allerdings nach: Die Funktion macht zuviel.
Ich wuerde versuchen, den Teil 'ohne Speichern' auf Biegen und
Brechen als 2.-ten Teil der Variante 'mit Speichern' hinzukriegen.
Willst Du Speichern, dann sind halt 2 Aufrufe erforderlich. Willst
Du nicht Speichern entfaellt der erste.

Jetzt liegen die Dinge allerdings wieder anders, ich habe die Funktion
nur in der abgeleiteten Klasse, sie berechnet was und speichert die
Ergebnisse ab.

Quote:
Ganz ehrlich: Ich denke wir sind an einem Punkt angelangt, an dem
ich nur mehr noch mehr Verwirrung stifte. Ich hoffe ich konnte
Dir einige Ideen geben, was man alles machen koennte.

Du hast mir ein paar gute Ideen und Denkanstöße gegeben, vielen Dank
dafür! Ich werde die ganzen Ideen jetzt mal in Ruhe zusammentragen und
verschiedene Variationen durchspielen. Vielleicht melde ich mich dann
später nochmal hier - Probleme oder was zum diskutieren gibt es ja
immer ;-)

Ciao,
Torsten

PS: Ich muss schon sagen, diese Newsgroup ist echt super. Hier wird
einem richtig weiter geholfen, kaum sinnlose Diskussionen oder
Endlos-Threads. Weiter so!

--
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.