PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Fragen zur objekt-orientierten Programmierung


Sinnoh
2007-08-12, 21:07:48
Hey,

also OOP ist ja in aller Munde und so dachte ich, das schau ich mir auch mal an mit einer dazu passenden Sprache. Da kommen ja vorallem Java und C# in Frage, und hier im forum wird ja auch oft zu C# geraten (aufgrund der Eleganz, was auch immer dies bei einer Programmiersprache heißen mag xD).

1.)

Die Datenkapselung ist ja ein sehr wichtiges Merkmal. D.h. Daten von Objekten sollten nicht öffentlich veränderbar sein, sondern nur über Methoden dieses Objektes, die das kontrolliert durchführen und aufpassen, dass da auch richtige Daten reinkommen. Aber kann es sein, dass das nichtmal die Sprachen selbst richtig machen? Oder warum darf ich einer Textbox mit

textbox1.text = "text";

einen Text zuweisen, statt mit textbox1.settext("text"); ?

Widerspricht der Datenkapselung doch völlig ?! :)


2.)

Wo wir gerade bei Daten sind: ich will in meinem Programm anfangs ein paar Daten festlegen, die dann von mehreren Objekten benutzt werden sollen. Da das formloads-Event (ich rede jetzt von C#, bei Java wirds nicht arg anders sein) ja beim Start ausgeführt wird, dachte ich dort ist der richtige Platz dafür:

private void Form1_Load(object sender, EventArgs e)
{
//hier Array mit Daten erstellen
}

Wenn ich das Array jetzt aber später in einem anderen Ereignis (textchanged, mousemoved etc) benutzen will, bekomme ich die Meldung das Array wäre unbekannt. Zwar könnte ich das Array auch erst innerhalb dieser festlegen, jedoch wäre ja dann Redunanz gegeben und das Array x mal vorhanden.

3.)

Wie kann ich ein Ereignis in einem anderen auslösen? Ich will z.b. nur auf das Ereignis "Maus wurde bewegt" reagieren, wenn davor das Ereignis "Taste X wurde gedrückt" eintrat. Beides getrennt funktioniert, aber wenn ich den Code für die Maus in den Bereich des Tastenevents einfüge, gibts nen Fehler.


Danke :)

sinnoh
2007-08-12, 21:12:12
Achso, ich merke gerade dass Frage 3 sehr ungenau ist:

public void MyKeyDown(object sender, KeyEventArgs e)
{
//wenn key down, mache dies und das
}

public void Mousemove(object sender, KeyEventArgs e)
{
//wenn maus bewegt, mache dies und das
}

funktioniert getrennt bestens,

public void MyKeyDown(object sender, KeyEventArgs e)
{
public void Mousemove(object sender, KeyEventArgs e)
{
//wenn maus bewegt, mache dies und das
}
}

allerdings nicht.

][immy
2007-08-12, 21:16:54
Hey,

also OOP ist ja in aller Munde und so dachte ich, das schau ich mir auch mal an mit einer dazu passenden Sprache. Da kommen ja vorallem Java und C# in Frage, und hier im forum wird ja auch oft zu C# geraten (aufgrund der Eleganz, was auch immer dies bei einer Programmiersprache heißen mag xD).

1.)

Die Datenkapselung ist ja ein sehr wichtiges Merkmal. D.h. Daten von Objekten sollten nicht öffentlich veränderbar sein, sondern nur über Methoden dieses Objektes, die das kontrolliert durchführen und aufpassen, dass da auch richtige Daten reinkommen. Aber kann es sein, dass das nichtmal die Sprachen selbst richtig machen? Oder warum darf ich einer Textbox mit

textbox1.text = "text";

einen Text zuweisen, statt mit textbox1.settext("text"); ?

Widerspricht der Datenkapselung doch völlig ?! :)


Stichwort Properties ;)
das sind in C# quasi Get/Set Methoden in einem. Für gewöhnlich setzt du variablen darüber. Nach außen sieht es aber aus als wäre es ein völlig normale variable.


2.)

Wo wir gerade bei Daten sind: ich will in meinem Programm anfangs ein paar Daten festlegen, die dann von mehreren Objekten benutzt werden sollen. Da das formloads-Event (ich rede jetzt von C#, bei Java wirds nicht arg anders sein) ja beim Start ausgeführt wird, dachte ich dort ist der richtige Platz dafür:

private void Form1_Load(object sender, EventArgs e)
{
//hier Array mit Daten erstellen
}

Wenn ich das Array jetzt aber später in einem anderen Ereignis (textchanged, mousemoved etc) benutzen will, bekomme ich die Meldung das Array wäre unbekannt. Zwar könnte ich das Array auch erst innerhalb dieser festlegen, jedoch wäre ja dann Redunanz gegeben und das Array x
mal vorhanden.



die variablen die du innerhalb von methoden erzeugst sind (wenn du keine externe referenz darauf hast) am ende der methode auch wieder weg. Hier würden sich klassen-variablen anbieten. also variablen die du im Kopf der klasse definierst, und dann bei der ersten benutzung initialisierst. dadurch kannst du die entsprechenden variablen/objekte auch in den anderen methoden verwenden.



3.)

Wie kann ich ein Ereignis in einem anderen auslösen? Ich will z.b. nur auf das Ereignis "Maus wurde bewegt" reagieren, wenn davor das Ereignis "Taste X wurde gedrückt" eintrat. Beides getrennt funktioniert, aber wenn ich den Code für die Maus in den Bereich des Tastenevents einfüge, gibts nen Fehler.


z.B. in dem du eine globle boolsche variable definierst und diese sobald eine maustaste gedrückt wurde auf true setzt. dann kannst du im mousmove-event abfragen ob die taste gedrückt wurde.
Wird sie wieder losgelassen kannst du die variable wieder auf false setzen lassen per event.

andererseits würde es sich anbieten das übergebene "Maus"-Objekte abzufragen ob eine Taste gedrückt wurde ;)

OOP halt ;)

edit:
Achso, ich merke gerade dass Frage 3 sehr ungenau ist:



public void MyKeyDown(object sender, KeyEventArgs e)

{

//wenn key down, mache dies und das

}



public void Mousemove(object sender, KeyEventArgs e)

{

//wenn maus bewegt, mache dies und das

}



funktioniert getrennt bestens,



public void MyKeyDown(object sender, KeyEventArgs e)

{

public void Mousemove(object sender, KeyEventArgs e)

{

//wenn maus bewegt, mache dies und das

}

}



allerdings nicht.

innerhalb von methoden/funktionen kannst du keine neuen methoden/funktionen erzeugen. das geht ansich nur bei javascript (vielleicht auch noch wo anders, aber die sprache kenne ich dann nicht)


edit2:
achja ein Beispiel für eine Property

private TextBox _box = new TextBox();

public string MeinTextBoxText
{
get
{
return this._box.Text;
}
set
{
this._box.Text = value; // Bei Properties ist der übergebenen wert immer "value"
}
}

DaEmpty
2007-08-12, 21:18:22
. Aber kann es sein, dass das nichtmal die Sprachen selbst richtig machen? Oder warum darf ich einer Textbox mit

textbox1.text = "text";

einen Text zuweisen, statt mit textbox1.settext("text"); ?

Widerspricht der Datenkapselung doch völlig ?! :)

1. anschauen was Properties in C# sind
2. Daten kapselt, speichert und verwaltet man in Datenobjekten und nicht in Oberflächenelementen. Die GUI dient nur zur Ein- und Ausgabe.


Wo wir gerade bei Daten sind: ich will in meinem Programm anfangs ein paar Daten festlegen, die dann von mehreren Objekten benutzt werden sollen.

Einen Manager bauen, diese zentralen Daten/Datenobjekte verwaltet. Hier macht oft ein Singleton Sinn.
Dort kann man jenachdem was es ist, die notwendigen Daten im Konstruktor erzeugen. Der Konstruktor wird, abgesehen von statischen Funktionen, immer vor allem anderen ausgeführt.

Wie kann ich ein Ereignis in einem anderen auslösen? Ich will z.b. nur auf das Ereignis "Maus wurde bewegt" reagieren, wenn davor das Ereignis "Taste X wurde gedrückt" eintrat.
Schau dir mal an was eine Statemachine ist.

sinnoh
2007-08-12, 22:18:02
Danke für Eure Antworten ;)

Noch eine letzte Frage zu den angesprochenen Daten: ich hatte ja erst ein Array, welches aber nur in einem Objekt bekannt war. Also erstelle ich nun wie von euch vorgeschlagen eine Klasse DataLoader, in dessen Konstruktor ich die Daten aufbereite. Wenn ich diese Daten nun in Klassenvariablen packe, kann ich sie auch anderorts benutzen. Allerdings sind das Zeilen aus einer Textdatei, so 200 Stück. Ich kann doch jetzt nicht 200 Klassenvariablen erstellen? Das war auc hder Grund warum ich ein Array hatte, da haben die schön reingepasst.

][immy
2007-08-12, 22:46:07
Danke für Eure Antworten ;)

Noch eine letzte Frage zu den angesprochenen Daten: ich hatte ja erst ein Array, welches aber nur in einem Objekt bekannt war. Also erstelle ich nun wie von euch vorgeschlagen eine Klasse DataLoader, in dessen Konstruktor ich die Daten aufbereite. Wenn ich diese Daten nun in Klassenvariablen packe, kann ich sie auch anderorts benutzen. Allerdings sind das Zeilen aus einer Textdatei, so 200 Stück. Ich kann doch jetzt nicht 200 Klassenvariablen erstellen? Das war auc hder Grund warum ich ein Array hatte, da haben die schön reingepasst.

du kannst auch weiterhin ein array nutzen. du könntest ja z.B. eine Property für das Array schreiben und die Referenz dahin übergeben wo es gerade benötigt wird.

Übrigends, wenn du einfach alle textzeilen in einen string reinschiebst, dann kannst du diese auch nachher noch zeile für zeile auslesen (wenn es denn nötig sein sollte).

auch ein Array kannst du dynamisch vergrößern, wobei die einfachste methode dazu eine ArrayList oder eine generic list ist.
die Arraylist kann alle möglichen objekte beinhalten wie auch ein Array und du kannst jederzeit aus der arraylist ein normales array machen. Die Arraylisten findest du unter System.Collections

Dann würde das ganze in etwa so aussehen
ArrayList list = new ArrrayList();
list.Add("hier den Text bzw die Variable");

das schlimme bei normalen arraylisten ist, das es denen so ziemlich egal ist welche objekte du ihnen gibst. daher ist man bei arraylisten immer mit "boxing" beschäftigt. D.h. um den wert wieder rauszubekommen musst du das objekt was du zurück bekommen in den richtigen typ zurück-casten. das sehe dann ungefähr so aus
string eintrag = list[0].toString();

oder

string eintrag = (string) list[0];

das casten benötigt jedesmal etwas zeit. daher wurden in .net 2.0 Generics eingeführt. damit kannst du z.B. solche listen erstellen und bekommst direkt den erwünschten typ zurück, kannst allerdings auch nur (.. naja ansich ist das ein vorteil) diesen typ in das array reinkippen.
das ginge dann über den namespace System.Collections.Generics (korregiert mich wenn ich das falsch geschrieben habe ... ich bekenne mich schuldig bei sowas eigentlich fast nur noch intellisence zu verwende ^^)
das würde dann so aussehen

List<string> liste = new List<string>();

liste.Add("Hier dein eintrag oder dein String-objekt");
zum auslesen einfach wie gehabt
string eintrag = liste[0];

und fertig ;)

Sinnoh
2007-08-12, 23:41:25
@][immy: Danke für diesen ausführlichen Beitrag! ;)

Also ich habe nicht gewusst, dass man Arrays auch als Klassenvariablen benutzen kann. Tatsächlich kann ich nun an anderer Stelle mit objektname.arrayname[index] dafauf zugreifen und es wie ein normales Array behandeln. Das mit den Properties muss ich mir mal anschauen, hauptsache ist erstmal dass es funktioniert, dann kommt der Feinschliff (oder bei meinem Gefrickel eher der Grobschliff ^^).

Zu der Arraylist: du wirst lachen, aber ich habe die Zeilen anfangs sogar in einer Arraylist gespeichert. Allerdings besteht eine Zeile immer aus 2 Teilen: Befehl und der dazugehörige Wert (Beispiel: maxclients = 1000). Deshalb dachte ich im Nachinein, ein zweidimensionales Array wäre da besser und habs umgebaut. Die erste Spalte des Arrays hat also den Befehl (maxclient), die zweite den dazugehörigen Wert (1000), und so geht das mit allen ~200 Zeilen. Keine Ahnung ob das elegant ist, aber ich dachte da kann ich zum ersten mal mehrdimensionale Arrays austesten.

del_4901
2007-08-12, 23:47:55
@][immy: Danke für diesen ausführlichen Beitrag! ;)

Also ich habe nicht gewusst, dass man Arrays auch als Klassenvariablen benutzen kann. Tatsächlich kann ich nun an anderer Stelle mit objektname.arrayname[index] dafauf zugreifen und es wie ein normales Array behandeln. Das mit den Properties muss ich mir mal anschauen, hauptsache ist erstmal dass es funktioniert, dann kommt der Feinschliff (oder bei meinem Gefrickel eher der Grobschliff ^^).

Zu der Arraylist: du wirst lachen, aber ich habe die Zeilen anfangs sogar in einer Arraylist gespeichert. Allerdings besteht eine Zeile immer aus 2 Teilen: Befehl und der dazugehörige Wert (Beispiel: maxclients = 1000). Deshalb dachte ich im Nachinein, ein zweidimensionales Array wäre da besser und habs umgebaut. Die erste Spalte des Arrays hat also den Befehl (maxclient), die zweite den dazugehörigen Wert (1000), und so geht das mit allen ~200 Zeilen. Keine Ahnung ob das elegant ist, aber ich dachte da kann ich zum ersten mal mehrdimensionale Arrays austesten.
Warum machst du dir nicht einfach eine Klasse ... welche einen String und eine Value hat, welche du dann in das Array(list) reinsteckst. Das währe elegant gewesen. Du kannst ja mal versuchen das ganze in eine "Map" zu stecken. Ich glaube das C# Equalivalent davon ist die "HashTable", wenn du häufig darin suchen musst, dann lohnt sich das.

Monger
2007-08-13, 11:31:47
Das ist für Umsteiger irgendwie ganz klassisch: die denken immer in Arrays, Strings und Integers.

Die Stärke von objektorientierten Sprachen ist ja aber gerade, dass man auch wesentlich komplexere Datentypen formulieren und nutzen kann, und auch sollte.
Ein Array ist oftmals die schlechteste Wahl, weil es starr und nicht besonders aussagekräftig ist. Schau dir mal wenigstens List(of T) und Dictionary(of T) an. Beides Konstrukte, die man sehr häufig gebrauchen kann.

Simon
2007-08-13, 11:57:26
Die Datenkapselung ist ja ein sehr wichtiges Merkmal. D.h. Daten von Objekten sollten nicht öffentlich veränderbar sein, sondern nur über Methoden dieses Objektes, die das kontrolliert durchführen und aufpassen, dass da auch richtige Daten reinkommen.
Mit dieser Aussage wäre ich etwas vorsichtiger. Klar, das ist der klassische Lehrsatz und wird so gelehrt. Aber überall anwenden würde ich das nicht...
Wir haben hier einige Komponenten, wo keinerlei Information Hiding betrieben wird. Wozu auch? Das sind grundlegende Sachen, wo man seine Design Entscheidungen nicht verstecken braucht. Ein populäres Beispiel sind hier die Vektor-Klassen (in Raytracern). Mit Information Hiding sieht der Code schrecklich aus und ich sehe auch keinerlei Sinn darin, die Attribute zu verstecken. Mal von dem großen Performance Hit durch die andauernden Funktionsausrufe ganz abgesehen.

Gast
2007-08-13, 12:29:09
Mit dieser Aussage wäre ich etwas vorsichtiger. Klar, das ist der klassische Lehrsatz und wird so gelehrt. Aber überall anwenden würde ich das nicht...
Wir haben hier einige Komponenten, wo keinerlei Information Hiding betrieben wird. Wozu auch? Das sind grundlegende Sachen, wo man seine Design Entscheidungen nicht verstecken braucht. Ein populäres Beispiel sind hier die Vektor-Klassen (in Raytracern). Mit Information Hiding sieht der Code schrecklich aus und ich sehe auch keinerlei Sinn darin, die Attribute zu verstecken. Mal von dem großen Performance Hit durch die andauernden Funktionsausrufe ganz abgesehen.
Sowas sollte von vernünftigen Compilern eigentlich geinlined werden...

Simon
2007-08-13, 12:48:24
Sowas sollte von vernünftigen Compilern eigentlich geinlined werden...
Wenn man sich auf die Geschwindigkeit konzentriert und alles andere außen vor lässt: Dann nenn mir mal einen vernünftigen, außer den von MS, Intel und GNU. Alle drei tun es nämlich nicht, auch mit entsprechenden Einstellungen.

Gast
2007-08-13, 16:02:15
Wenn man sich auf die Geschwindigkeit konzentriert und alles andere außen vor lässt: Dann nenn mir mal einen vernünftigen, außer den von MS, Intel und GNU. Alle drei tun es nämlich nicht, auch mit entsprechenden Einstellungen.
Die trivialen Methode (a la "int getValue()" ) schreibt man bei C++ normalerweise schon in den Header. Da bleibt dem Compiler ja eigentlich keine andere Wahl als das bei jedem Aufruf zu inlinen.

Neomi
2007-08-13, 23:10:05
Die trivialen Methode (a la "int getValue()" ) schreibt man bei C++ normalerweise schon in den Header. Da bleibt dem Compiler ja eigentlich keine andere Wahl als das bei jedem Aufruf zu inlinen.

Die Compilezeit steigt, es hat keinen praktischen Nutzen wenn Werte nur durchgereicht werden, nicht durchoptimierte Version (wie z.B. die gar nicht optimierten Debug-Konfigurationen) leiden enorm, nichtmal der Komfort bei der Benutzung steigt. Man sollte nichts einsetzen, um es einzusetzen, sondern weil es sinnvoll ist. Und das sind Setter und Getter bei Vektoren und Matrizen wohl kaum.

Gast
2007-08-14, 10:59:17
Das ist für Umsteiger irgendwie ganz klassisch: die denken immer in Arrays, Strings und Integers.

Die Stärke von objektorientierten Sprachen ist ja aber gerade, dass man auch wesentlich komplexere Datentypen formulieren und nutzen kann, und auch sollte.das hat eigentlich nichts mit objektorientierter Programmierung zu tun, sondern ist schon aus der prozeduralen Programmierung bekannt: dort kann man beliebig komplexe Datenstrukturen (struct in C, record in Pascal) erstellen, darum wird diese Arte der Programmierung ja auch strukturierte Programmierung genannt.
Ich gebe allerdings zu, daß ich, bevor ich mit OOP angefangen habe, nie so recht die Motivation hatte, structs/records zu verwenden...

Monger
2007-08-14, 11:15:37
das hat eigentlich nichts mit objektorientierter Programmierung zu tun, sondern ist schon aus der prozeduralen Programmierung bekannt: dort kann man beliebig komplexe Datenstrukturen (struct in C, record in Pascal) erstellen, darum wird diese Arte der Programmierung ja auch strukturierte Programmierung genannt.
Ich gebe allerdings zu, daß ich, bevor ich mit OOP angefangen habe, nie so recht die Motivation hatte, structs/records zu verwenden...

Du hast natürlich recht, dass das nicht unbedingt eine Domäne der objektorientierten Programmierung ist.

Aber: um Datenstrukturen auch allgemein wiederverwenden zu können, braucht man Abstraktion. Und das kam halt erst mit den objektorientierten Sprachen wirklich auf. Deshalb hat man sich vorher selten den Stress gegeben besonders komplexe Datentypen zu basteln, weil sich der Aufwand einfach nicht gelohnt hat.

Gast
2007-08-14, 11:22:00
Mit dieser Aussage wäre ich etwas vorsichtiger. Klar, das ist der klassische Lehrsatz und wird so gelehrt. Aber überall anwenden würde ich das nicht...
Wir haben hier einige Komponenten, wo keinerlei Information Hiding betrieben wird. Wozu auch? Das sind grundlegende Sachen, wo man seine Design Entscheidungen nicht verstecken braucht. als jemand, der mit diesem Thema schon oft konfrontiert war, und eigentlich immer heilfroh war, daß er sich ans Information Hiding gehalten hat, will ich deine Frage gerne beantworten:

- zum einen sind das die besseren Kontrollmöglichkeiten. Stell dir vor, du bemerkst, daß deine Membervariable irgendwo Werte zugewiesen bekommt wo sie das nicht soll. Eine set()-Methode macht es viel einfacher, diese Stelle ausfindig zu machen, z.B. kannst du in sie Tracing einfügen oder beim Debuggen einen Breakpoints reinsetzen. Ebenso kannst du so viel leichter zu Testzwecken Manipulationen der Variablen unterbinden, indem du einfach eine Zeile der set()-Methode deaktivierst.

- zum zweiten erleichtert es Änderungen am internen Design. Vielleicht kommt dir irgendwann die Idee, daß es gar nicht so sinnvoll ist, diese Membervariable zu haben. Vielleicht sind andere Membervariablen, die sich aus dieser berechnen, viel sinnvoller. Dann kannst du einfach die set()-Methode beibehalten und die Berechnung in diese packen. Oder stell dir vor, du baust eine Vektor-Klasse, und speicherst die Elemente erst in einem einfachen Array. Später kommt dir dann die Idee, daß die sich viel effizienter auf andere Weise speichern ließen. Die Methoden setValue(int i) und getValue(int i) kannst du dann beibehalten.

Ein populäres Beispiel sind hier die Vektor-Klassen (in Raytracern). Mit Information Hiding sieht der Code schrecklich ausdas Beispiel hätte ich gerne näher ausgeführt.

del_4901
2007-08-14, 13:30:36
als jemand, der mit diesem Thema schon oft konfrontiert war, und eigentlich immer heilfroh war, daß er sich ans Information Hiding gehalten hat, will ich deine Frage gerne beantworten:

- zum einen sind das die besseren Kontrollmöglichkeiten. Stell dir vor, du bemerkst, daß deine Membervariable irgendwo Werte zugewiesen bekommt wo sie das nicht soll. Eine set()-Methode macht es viel einfacher, diese Stelle ausfindig zu machen, z.B. kannst du in sie Tracing einfügen oder beim Debuggen einen Breakpoints reinsetzen. Ebenso kannst du so viel leichter zu Testzwecken Manipulationen der Variablen unterbinden, indem du einfach eine Zeile der set()-Methode deaktivierst.
Dafür gibt es dependent Memory Breakpoints. Das unterbinden von Änderungen, das macht mir auch meine IDE, hab ich allerdings noch nie benötigt. Zu 95% funktionier nämlich mein Code auf anhieb ... das ist der Vorteil wenn man sich vorher Gedanken gemacht hat. Die restlichen 5% fallen in meine Eitelkeit und Critical Sections, was man beides ganz schlecht debuggen kann.


- zum zweiten erleichtert es Änderungen am internen Design. Vielleicht kommt dir irgendwann die Idee, daß es gar nicht so sinnvoll ist, diese Membervariable zu haben. Vielleicht sind andere Membervariablen, die sich aus dieser berechnen, viel sinnvoller. Dann kannst du einfach die set()-Methode beibehalten und die Berechnung in diese packen. Oder stell dir vor, du baust eine Vektor-Klasse, und speicherst die Elemente erst in einem einfachen Array. Später kommt dir dann die Idee, daß die sich viel effizienter auf andere Weise speichern ließen. Die Methoden setValue(int i) und getValue(int i) kannst du dann beibehalten.
Das wird bei einem Mathematischen Vektor nie auftreten. Auch in 100 Jahren nicht. Und wenn ich sowas wie Vector3f v; v.x = 3.0f oder v.yzx = 4.0f schreiben will, da bin ich viel zu faul für die () zu schreiben, das würde mir aber sowas von auf den Kranz gehen. Schreibarbeit für nichts und wiedernichts.

BTW, so oft scheinst du noch nicht damit konfrontiert gewesen zu sein, sonnst währn dir schon die Finger vom vielen schreiben abgefault, oder du wüsstest was Memory Breakpoints sind. (die braucht man nicht häufig, aber wenn man sie braucht, dann sind sie unverzichtbar)

Simon
2007-08-14, 14:15:50
- zum einen sind das die besseren Kontrollmöglichkeiten. Stell dir vor, du bemerkst, daß deine Membervariable irgendwo Werte zugewiesen bekommt wo sie das nicht soll. Eine set()-Methode macht es viel einfacher, diese Stelle ausfindig zu machen, z.B. kannst du in sie Tracing einfügen oder beim Debuggen einen Breakpoints reinsetzen. Ebenso kannst du so viel leichter zu Testzwecken Manipulationen der Variablen unterbinden, indem du einfach eine Zeile der set()-Methode deaktivierst.
Kann mit offenen Attributen auch problemlos debuggen. Hier hat die set-Methode keinerlei Vorteile...

- zum zweiten erleichtert es Änderungen am internen Design. Vielleicht kommt dir irgendwann die Idee, daß es gar nicht so sinnvoll ist, diese Membervariable zu haben. Vielleicht sind andere Membervariablen, die sich aus dieser berechnen, viel sinnvoller.
Klar, ich änder mal eben das grundlegende Design? :| :ucrazy3:

das Beispiel hätte ich gerne näher ausgeführt.

#1

Vec3 v;
...
v.x += sin(time);


#2

Vec3 v;
...

v.setX(v.getX()+sin(time));


Über die Beispiele an sich lasst sich sicherlich vortrefflich streiten ;D
Die erste Variante ist schöner und wesentlich schneller, dass das lästige Kopieren und Durch-die-Gegend-springen entfällt. Cache-Misses und Sprünge sind nie gut...

Die get/set-Methoden haben alle erstmal den Call-Overhead.

Ich denke (und offensichtlich einige andere hier auch ;) ), dass für grundlegende und kleine Klassen wie Vector, Ray, Matrix das Information Hiding absolut unnötig ist. Gerade bei Leuten, die erst mit OO angefangen haben, setzen dies überall und teilweise fanatisch ein, ohne wirklich drüber nachzudenken. Dieser Ansatz ist an solchen Stellen jedoch fehlgeleitet, versteckt er unnötigerweise Implementierungsdetails. Ein 3D-Vektor ist immer ein 3D-Vektor und besteht aus drei Komponenten und das wird sich auch sehr selten ändern. Es ist sinnvoll, die grundlegenden Design-Entscheidungen im ganzen System bekannt zu machen und den restlichen Code darauf aufzubauen. Daran ist auch nix falsch.
Ich sage nicht, dass man jetzt überhaupt kein Information Hiding mehr betreiben soll, sondern nur, wo es sinnvoll ist. Ohne Information Hiding gibt es den berüchtigten Maintenance Nightmare ;D

Dazu kommt die zusätzliche Schreibarbeit, wie von AlphaTier schon bemerkt.

Monger
2007-08-14, 14:30:43
Klar, ich änder mal eben das grundlegende Design? :| :ucrazy3:

Passiert schneller als man denkt. ;)
Och, ein Single reicht nicht mehr? Schnell mal ein Double draus machen... Mist, geht nicht.


Die get/set-Methoden haben alle erstmal den Call-Overhead.

Ehrlich gesagt halte ich das für ein Gerücht. Man müsste sich das natürlich mal im Bytecode anschauen, aber ich kann mir nicht vorstellen dass der Compiler aus einem Attributzugriff etwas anderes macht als aus einem Attributzugriff aus einer Methode heraus.

Und selbst wenn doch, ist das immer noch eine Premature Optimization, weil das nunmal die Aufgabe des Compilers, und nicht des Coders ist, da noch ein Quentchen Performance rauszuquetschen.


Ich denke (und offensichtlich einige andere hier auch ;) ), dass für grundlegende und kleine Klassen wie Vector, Ray, Matrix das Information Hiding absolut unnötig ist.

Bei Strukturen die keinerlei eigenes Verhalten haben, und bei denen sowieso keine Zugriffe beschränkt oder reglementiert werden sollen, und die nur Basisdatentypen verwenden, kann man imho auf Information Hiding verzichten.

Designentscheidungen hängen nunmal davon ab was man konkret macht. Auf der anderen Seite: gerade mit den Properties tut Information hiding eigentlich niemandem weh, und bringt nur Vorteile. Warum also darauf verzichten, vorallem nachdem moderne IDEs das meistens auch automatisiert können?

Coda
2007-08-14, 14:45:48
Passiert schneller als man denkt. ;)
Och, ein Single reicht nicht mehr? Schnell mal ein Double draus machen... Mist, geht nicht.
Erstmal gibt's dafür Templates und zweitens musst wenn du auf Doubles umstellst eh den ganzen Code ändern nicht nur die Vektorklasse.

Simon
2007-08-14, 14:48:36
Passiert schneller als man denkt. ;)
Hier zumindest nicht.

Och, ein Single reicht nicht mehr? Schnell mal ein Double draus machen... Mist, geht nicht.
Versteh ich nicht :confused:


typedef Vec3<float> Vec3f;
typedef Vec3<double> Vec3d;
typedef Vec3<uint8>....

Und selbst ohne Templates:

typedef struct
{
float x,y,z;
};
==>

typedef struct
{
double x,y,z;
};

Was geht daran jetzt nicht? :|

Ehrlich gesagt halte ich das für ein Gerücht. Man müsste sich das natürlich mal im Bytecode anschauen, aber ich kann mir nicht vorstellen dass der Compiler aus einem Attributzugriff etwas anderes macht als aus einem Attributzugriff aus einer Methode heraus.
Dann beweise das mal. Ich weiß, was ich hier gemessen und im Assembler Code gesehen und gemessen habe...

Und selbst wenn doch, ist das immer noch eine Premature Optimization, weil das nunmal die Aufgabe des Compilers, und nicht des Coders ist, da noch ein Quentchen Performance rauszuquetschen.
Das kannst du so nicht sagen. Wenn es deine Aufgabe ist, das Programm bis aufs letzte zu optimieren, dann mußt du auch sowas machen. Ich durfte es bei einem Raytracer machen und es bringt mehr als 10% (zumindest in unserem...)


Bei Strukturen die keinerlei eigenes Verhalten haben, und bei denen sowieso keine Zugriffe beschränkt oder reglementiert werden sollen, und die nur Basisdatentypen verwenden, kann man imho auf Information Hiding verzichten.
Äh, ja. Wenn Zugriff nicht beschränkt ist, braucht man kein Information Hiding. Tolle Sache :rolleyes: Aber darum gehts eigentlich gar nicht....


Auf der anderen Seite: gerade mit den Properties tut Information hiding eigentlich niemandem weh, und bringt nur Vorteile.
Äh, Properties? ;(

Gast
2007-08-14, 14:57:06
Getter und Setter sind immer dann sinnvoll, wenn Konvertierungen stattfinden bzw. intern mit anderen Werten oder Genauigkeiten gerechnet wird als nach außen hin kommuniziert wird. Außerdem kann man darin auch gleich andere Aufgaben zumindest anstoßen (z.B. durch einen weiteren Methodenaufruf).

Monger
2007-08-14, 14:59:57
Erstmal gibt's dafür Templates und zweitens musst wenn du auf Doubles umstellst eh den ganzen Code ändern nicht nur die Vektorklasse.
Nicht zwingend. Nehmen wir mal an, du würdest nicht nur ein Get und Set machen, sondern z.B. auch das Skalarprodukt ausrechnen wollen. Jetzt willst du die Präzision des Skalarproduktes erhöhen, ohne die Kompatibilität nach außen hin zu brechen. Mit Gettern und Settern könntest du das erreichen, ansonsten nicht.


Versteh ich nicht :confused:

typedef struct
{
float x,y,z;
};
==>
typedef struct
{
double x,y,z;
};

Was geht daran jetzt nicht? :|

Wenn das eine Bibliothek ist, und ein paar tausend Kunden genau diese Bibliothek nutzen, werden die sobald du so eine Änderung als Update einspielst dich an den nächsten Baum knüpfen! ;)

Information Hiding macht natürlich nur dann Sinn, wenn mehrere Leute auf die selben Ressourcen zugreifen, und eine Interface-Änderung größere Konsequenzen hat als man selbst als Entwickler absehen und anpassen kann.


Äh, Properties? ;(
Über welche Sprache sprechen wir denn hier gerade? Ich dachte, wir hätten es von C# ?!?
Ich bezog mich natürlich auch mit dem Compiler auf C#, in C++ gibt es schließlich keinen Bytecode.

Coda
2007-08-14, 15:13:39
Nicht zwingend. Nehmen wir mal an, du würdest nicht nur ein Get und Set machen, sondern z.B. auch das Skalarprodukt ausrechnen wollen. Jetzt willst du die Präzision des Skalarproduktes erhöhen, ohne die Kompatibilität nach außen hin zu brechen. Mit Gettern und Settern könntest du das erreichen, ansonsten nicht.
Was willst du denn mit erhöhter Präzission wenn danach eh wieder gerundet wird?
Leute. Sinnvolle Argumente und etwas Einsicht wäre manchmal angebracht.

Ich bin normal auch für striktes Information-Hiding, aber bei solchen Dingen ist es wirklich daneben.

Monger
2007-08-14, 15:17:03
Was willst du denn mit erhöhter Präzission wenn danach eh wieder gerundet wird?

Edit: ich formuliere es um - in dem Fall ist es ein blödes Beispiel, weil ein Skalarprodukt nur lesend ist. Aber sobald du irgendeine andere Operation einführst die auch schreibenden Zugriff hat, kann das durchaus Sinn machen. Zum Beispiel eine Normierung.

Es kommt halt auf den Fall an. Aber dass eine Klasse nach und nach erweitert wird, ist nichts ungewöhnliches. Jetzt vielleicht nicht gerade bei einer Vector Klasse, aber selbst bei Basisfunktionen ist das gar nicht so aus der Welt.

Gast
2007-08-14, 17:37:09
Dafür gibt es dependent Memory Breakpoints. kenne ich gar nicht. Welche IDEs untertsützen das denn?

Das unterbinden von Änderungen, das macht mir auch meine IDE,klingt interessant, wie stellt man das denn da ein?

hab ich allerdings noch nie benötigt. Zu 95% funktionier nämlich mein Code auf anhieb ... das ist der Vorteil wenn man sich vorher Gedanken gemacht hat.es kommt vor, daß man eine bereits fertig geschriebene Software weiterentwickeln will, und dabei auf die Idee kommt, Funktionalitäten einzubauen, an die man noch gar nicht gedacht hat, als man die Software geschrieben hat. Und über die man sich folglich auch gar keine Gedanken hat machen können.

Das wird bei einem Mathematischen Vektor nie auftreten. Auch in 100 Jahren nicht. Und wenn ich sowas wie Vector3f v; v.x = 3.0f oder v.yzx = 4.0f schreiben will, da bin ich viel zu faul für die () zu schreiben, das würde mir aber sowas von auf den Kranz gehen. Schreibarbeit für nichts und wiedernichts.gut, nehmen wir an du hast schön deine Vektoren mit sichtbaren v.x, v.y und v.z gemacht, und irgendwann kommt dir dann der Einfall, daß es nice to have wäre, wenn bei jeder Zuweisung einer Komponente direkt der Betrag des Vektors berechnet wird und zudem der neue Wert nur akzeptiert wird, wenn der resultierende Betrag innerhalb bestimmter Grenzen bleibt.
Mit einer set()-Methode geht das recht einfach:

Vector3::void setX(double newX)
{
// neuen Betrag berechnen
double new_norm = metric(newX, y, z);
// Exception wenn außerhalb der Grenzen
if (s < min || s > max)
throw "norm out of range";

// neuen x-Wert und neuen Betrag abspeichern
x = newX;
norm = new_norm;
}

mit deiner Lösung müßtest du überall, wo du ein v.x = ... stehen hast, eine solche Überprüfung einfügen.

BTW, so oft scheinst du noch nicht damit konfrontiert gewesen zu sein, sonnst währn dir schon die Finger vom vielen schreiben abgefault, oder du wüsstest was Memory Breakpoints sind. weiß ich wie gesagt tatsächlich nicht. Kann aber auch daran liegen, daß ich lange Zeit mit Dev-C++ gearbeitet habe, das nichtmal mit normalen Breakpoints klarkommt (hab dort als Debugger-Ersatz immer Tracing benutzt). In Delphi 3, Eclipse, KDevelop und Visual Studio 6, 2003 und 2005 habe ich von Memory Breakpoints indes auch noch nichts gesehen.

Gast
2007-08-14, 18:00:35
Klar, ich änder mal eben das grundlegende Design? :| :ucrazy3:Beispiel: ich habe mal an einem Programm geschrieben, in dem ein System modelliert, das eine Temperatur hat. Zuerst habe ich einfach eine Membervariable temperature gemacht. Irgendwann später fiel mir dann auf, daß die Temperatur selbst eher uninteressant war, und vielmehr der Boltzmann-Faktor exp(-E/kT) zählte. Statt diesen immer wieder neuzu berechnen, erwies es sich, da die Energie E nur einige wenige diskrete Werte annehmen konnte, als viel sinnvoller, bei jeder Temperaturänderung eine Tabelle für die möglichen Werte dieses Faktors zu berechnen und diese Tabelle dann immer nur auszulesen.
Dadurch, daß ich die Variable temperature private gemacht hatte nur über eine Methode setTemperature() auf sie zugegriffen werden konnte, konnte ich das Erstellen der Tabelle problemlos in dieser Methode unterbringen.
Dort konnte dann auch direkt geprüft werden, ob der neue Temperaturwert überhaupt sinnvoll war (> 0).



Vec3 v;
...

v.setX(v.getX()+sin(time));

in C++ macht man das so:

v.getX() += sin(time);
weil getX() als Rückgabetype double& hat ;)

Ich denke (und offensichtlich einige andere hier auch ;) ), dass für grundlegende und kleine Klassen wie Vector, Ray, Matrix das Information Hiding absolut unnötig ist.laß es mich mal so formulieren: für eine Vec-Klasse, die wirklich nur den Zweck hat, drei Wert x,y,z zu speichern, und niemals zu komplexeren Aktionen wie Betragsberechnungen o.ä. fähig sein soll, mag dein Standpunkt richtig sein. Ich würde so etwas aber auch nicht wirklich als richtige Klasse zählen, sondern als struct (auch wenn nach C++ Terminologie eine struct auch nur eine Klasse ist und es in Java gar keine struct gibt).

Simon
2007-08-14, 18:45:09
gut, nehmen wir an du hast schön deine Vektoren mit sichtbaren v.x, v.y und v.z gemacht, und irgendwann kommt dir dann der Einfall, daß es nice to have wäre, wenn bei jeder Zuweisung einer Komponente direkt der Betrag des Vektors berechnet wird und zudem der neue Wert nur akzeptiert wird, wenn der resultierende Betrag innerhalb bestimmter Grenzen bleibt.
Das wäre ein Clamping aufgrund der Länge (oder was auch immer) und hat in einer set-Methode nix zu suchen. Wenn ich was clampen will, ruf ich die entsprechenden Methoden auf.

mit deiner Lösung müßtest du überall, wo du ein v.x = ... stehen hast, eine solche Überprüfung einfügen.
Und wenn ich die Überprüfung nur an einigen Stellen will? ;)

in C++ macht man das so:
Code:
Schon klar, bis auf die Stelle, wo ein double zurückgegeben werden soll ;) Trotzdem muss in die Funktion gesprungen werden, die Werte kopiert, wieder zurückgesprungen, usw. Zu langsam und zu aufwendig.

laß es mich mal so formulieren: für eine Vec-Klasse, die wirklich nur den Zweck hat, drei Wert x,y,z zu speichern, und niemals zu komplexeren Aktionen wie Betragsberechnungen o.ä. fähig sein soll, mag dein Standpunkt richtig sein. Ich würde so etwas aber auch nicht wirklich als richtige Klasse zählen, sondern als struct (auch wenn nach C++ Terminologie eine struct auch nur eine Klasse ist und es in Java gar keine struct gibt).
Meine Vektor-Klassen kann auch Beträge und vielerlei andere Sachen berechnen ;) Das gleiche gilt auch für etliche andere, grundlegende Klassen.

Arokh
2007-08-14, 19:27:39
Das wäre ein Clamping aufgrund der Länge (oder was auch immer) und hat in einer set-Methode nix zu suchen. warum das denn nicht? Das ist ja eines der Goodies von set-Methoden, daß man da einen Wert auf Zulässigkeit überprüfen kann.

Wenn ich was clampen will, ruf ich die entsprechenden Methoden auf.vor oder nach der Zuweisung? Also so:

// erste zuweisen, dann überprüfen:
v.x = 1.e+99;
bool valid = v.checkValidity();

oder so:

// erst prüfen, dann zuweisen:
double new_x = 1.e+99;
if (v.checkValidity(new_x))
v.x = new_x;

?
Im ersten Fall ist dein Vektor hinüber, da der alte Wert verlorengegangen ist. Der zweite Fall hat die gleiche Funktionalität wie meine set-Methode, ist nur viel mehr Schreibaufwand (und damit Fehleranfälligkeit), da du das überall eintippen mußt wo du v.x verändern willst. Also das Gegenteil von dem was du erreichen willst.

Und wenn ich die Überprüfung nur an einigen Stellen will? ;)na dann schreibst du in die set-Routine zusätzlich einen bool-Parameter, der angibt, ob eine Überprüfung stattfinden soll oder nicht. Kannst als default-Wert ja false nehmen.

Trotzdem muss in die Funktion gesprungen werden, die Werte kopiert, wieder zurückgesprungen, usw. Zu langsam und zu aufwendig.wenn es um Performance (im Sinne von Laufzeit-Performance, nicht Schreibaufwand) geht, dann ist klar, daß man da auch mal Kompromisse in Sachen Eleganz machen muß.

Meine Vektor-Klassen kann auch Beträge und vielerlei andere Sachen berechnen ;) in diesem Fall stimme deine Behauptung nicht, daß es sich um eine kleine Klasse handeln würde. Spätestens dann wenn die Klasse anfängt Daten zu speichern, die aus den x,y,z berechnet werden, wie der Verktorlänge, wird ein direktes Manipulieren von x,y,z gefährlich. Wie gesagt, wenn es um ein Maximum an Laufzeit-Performance geht, und das meßbar auf diese Weise erreichbar ist, dann kann man das akzeptieren.
Wenn es aber nur auf das Aussehen des Quellcodes ankommt, weiß ich wirklich nicht, was an den Lösungen

v.addToX( sin(time) );
// oder
v.getX() += sin(time);

gegenüber

v.x += sin(time);
so schrecklich sein soll.

del_4901
2007-08-15, 00:15:43
kenne ich gar nicht. Welche IDEs unterstützen das denn?

http://msdn2.microsoft.com/en-us/library/350dyxd0(VS.80).aspx
VS kennt noch andere lustige Breakpoints
http://msdn2.microsoft.com/en-us/library/ktf38f66(VS.80).aspx

Intel hat noch spezielle Tools um Critical Sections, Race Condtions und Deadlocks zu finden ... auch sehr nett!


klingt interessant, wie stellt man das denn da ein?

http://msdn2.microsoft.com/de-de/library/4dt5w8ta(VS.80).aspx
Um das automatisch zu machen kann man sich vllt ein Macro schreiben (ich bin mir da aber nicht sicher ob man schreibenden Zugriff auf Locals hat ... hab ich noch nie gebraucht ... mal abgesehen von dem einen Hack)
SoftICE/Tsearch können jedenfalls Variablen freezen (das hab ich selbst schon gemacht) ... Aber das braucht man, wie gesagt, eh blos zum hacken


es kommt vor, daß man eine bereits fertig geschriebene Software weiterentwickeln will, und dabei auf die Idee kommt, Funktionalitäten einzubauen, an die man noch gar nicht gedacht hat, als man die Software geschrieben hat. Und über die man sich folglich auch gar keine Gedanken hat machen können.

Ein gutes Design kennt solche Probleme nicht. Nehmt mich als SoftwareArchitekten ... nen besseren gibs eh ned ... *auf Holz klopf*


gut, nehmen wir an du hast schön deine Vektoren mit sichtbaren v.x, v.y und v.z gemacht, und irgendwann kommt dir dann der Einfall, daß es nice to have wäre, wenn bei jeder Zuweisung einer Komponente direkt der Betrag des Vektors berechnet wird und zudem der neue Wert nur akzeptiert wird, wenn der resultierende Betrag innerhalb bestimmter Grenzen bleibt.
Mit einer set()-Methode geht das recht einfach:

Vector3::void setX(double newX)
{
// neuen Betrag berechnen
double new_norm = metric(newX, y, z);
// Exception wenn außerhalb der Grenzen
if (s < min || s > max)
throw "norm out of range";

// neuen x-Wert und neuen Betrag abspeichern
x = newX;
norm = new_norm;
}

mit deiner Lösung müßtest du überall, wo du ein v.x = ... stehen hast, eine solche Überprüfung einfügen.

Das mach ich dann wenn ich's brauch und nicht bei jeder Zuweisung ... typisch Java Programmierer <- sorry ... das schoss mir so in den Kopf

weiß ich wie gesagt tatsächlich nicht. Kann aber auch daran liegen, daß ich lange Zeit mit Dev-C++ gearbeitet habe, das nichtmal mit normalen Breakpoints klarkommt (hab dort als Debugger-Ersatz immer Tracing benutzt). In Delphi 3, Eclipse, KDevelop und Visual Studio 6, 2003 und 2005 habe ich von Memory Breakpoints indes auch noch nichts gesehen.
Augen auf im Straßenverkehr ... ok ich hab's auch erst beim hacken gelernt ... so oft brach man dei Dinger nämlich nicht ... aber ganz gut zu wissen das es sie gibt ... und manchmal sollte man einfach auch das Inhaltsverzeichniss der Doku seiner IDE durchforsten ... da findet man "manchmal" ganz nützliche Dinge. Ok, die MSDN machts einem da auch leicht ... :)

Monger
2007-08-15, 08:43:19
Das mach ich dann wenn ich's brauch und nicht bei jeder Zuweisung ... typisch Java Programmierer <- sorry ... das schoss mir so in den Kopf

Also, entweder hat ein Objekt eben das Verhalten, dass es auf Bereichslängen prüft und normiert, oder eben nicht.

Das ist natürlich eine Designfrage. Aber wenn von außen nicht erkennbar ist wo denn die Bereichsgrenzen liegen sollen, MÜSSEN sie zwangsläufig vom Objekt selbst verwaltet werden.

DaEmpty
2007-08-15, 10:14:10
kenne ich gar nicht. Welche IDEs untertsützen das denn?
Breakpoint sind meistens eine Hardwaresache. So ziemlich jeder Debugger kann deswegen auch mit Memory Breakpoints aka Data Breakpoints aka Watchpoints umgehen.

Wenn deine IDE nicht mit solchen grundlegenden Dingen umgehen kann, würde ich sehr schnell auf eine andere wechseln. Debugging macht einen relativ großen Teil der Entwicklungszeit aus, womit die Debuggingfunktionalität eine der wichtigsten Funktionen einer IDE ist. MS ist da imo momentan führend, aber verpeilt es zB auch noch die Pluginschnittstelle für die Debuganzeige richtig zu dokumentieren, obwohl es ein ziemliches cooles Feature ist.

Gast
2007-08-15, 13:42:11
Wenn deine IDE nicht mit solchen grundlegenden Dingen umgehen kann, würde ich sehr schnell auf eine andere wechseln.woher nehmen wenn nicht stehlen? Dev-C++ ist einer wenigen IDEs für C++, die kostenlos erhältlich sind.
Inzwischen habe ich zwar auch Visual Studio, aber der MS-Compiler kann halt nicht überall mit dem gcc mithalten.

Debugging macht einen relativ großen Teil der Entwicklungszeit aus, womit die Debuggingfunktionalität eine der wichtigsten Funktionen einer IDE ist. wem sagst du das?

DaEmpty
2007-08-15, 14:03:01
Inzwischen habe ich zwar auch Visual Studio, aber der MS-Compiler kann halt nicht überall mit dem gcc mithalten.
Hast du auch eine genauere Begründung dafür?

Coda
2007-08-15, 14:58:42
Die würde ich auch gerne haben. Ich wüsste nicht wo GCC dem 2005er Compiler von MS noch überlegen wäre.

Gast
2007-08-15, 15:06:08
Hast du auch eine genauere Begründung dafür?bei einem Programm, das numerisch Differentialgleichungen löst, erreichte ich beim gcc mit -O3 800 Durchgänge pro Sekunde, mit Visual Studio nur 250.

Gast
2007-08-15, 15:31:29
bei einem Programm, das numerisch Differentialgleichungen löst, erreichte ich beim gcc mit -O3 800 Durchgänge pro Sekunde, mit Visual Studio nur 250.
Unwahrscheinlicher Fall: Du hast einen extrem seltenen Spezialfall getroffen, bei dem der GCC glänzt und der MS Compiler komplett versagt.
Wahrscheinlicher Fall: Du hast irgendwas an den Einstellungen verbockt, Release mit Debugger im Hintergrund laufen lassen oä.

Solche Performanceunterschiede gibt es zwischen den gängigen Compilern nicht.

Dafür hat man mit dem GCC einen Bürokratencompiler, der bei allem gleich rumheult "kann ich nicht, will ich nicht, machs doch selber, dass könnte vielleicht gegen den Standard sein", und es mir mit unbrauchbaren Fehlermeldungen garniert (warum haben die Fehlermeldungen nicht eine Nummer und Dokumentation?).
Mein Code muss generell mit beiden Compilern laufen und die Arbeit mit dem GCC finde ich wesentlich unangenehmer.

del_4901
2007-08-15, 15:35:58
Unwahrscheinlicher Fall: Du hast einen extrem seltenen Spezialfall getroffen, bei dem der GCC glänzt und der MS Compiler komplett versagt.
Wahrscheinlicher Fall: Du hast irgendwas an den Einstellungen verbockt, Release mit Debugger im Hintergrund laufen lassen oä.

Solche Performanceunterschiede gibt es zwischen den gängigen Compilern nicht.

Dafür hat man mit dem GCC einen Bürokratencompiler, der bei allem gleich rumheult "kann ich nicht, will ich nicht, machs doch selber, dass könnte vielleicht gegen den Standard sein", und es mir mit unbrauchbaren Fehlermeldungen garniert (warum haben die Fehlermeldungen nicht eine Nummer und Dokumentation?).
Mein Code muss generell mit beiden Compilern laufen und die Arbeit mit dem GCC finde ich wesentlich unangenehmer.
Das kann ich so unterschreiben. Nichtmal der intel Compiler zieht den anderen so extrem davon.

Simon
2007-08-15, 15:36:36
bei einem Programm, das numerisch Differentialgleichungen löst, erreichte ich beim gcc mit -O3 800 Durchgänge pro Sekunde, mit Visual Studio nur 250.
Sowas ähnliches hab ich hier auch. Eine meiner Rechnungen ist unter Linux mit GCC 4.2 10-20% schneller als unter Windows mit VC2005. Warum auch immer. Mangels GCC 4.2 für Windows kann ich nicht genauer testen, an was es liegt...

Gast
2007-08-16, 23:42:22
Unwahrscheinlicher Fall: Du hast einen extrem seltenen Spezialfall getroffen, bei dem der GCC glänzt und der MS Compiler komplett versagt.
Wahrscheinlicher Fall: Du hast irgendwas an den Einstellungen verbockt, Release mit Debugger im Hintergrund laufen lassen oä.

Solche Performanceunterschiede gibt es zwischen den gängigen Compilern nicht.kann es vielleicht mit den mitgelieferten Bibliotheken zu tun haben? Mein Programm nutzt massiv std::complex<double>. Testweise habe ich mal auf eine eigene komplexe Zahlen-Klasse MyComplex umgestellt, dann wurden beide Varianten, gcc und VS2003, spürbar langsamer und lagen auch viel näher beisammen, hier mal meine Benchmark-Ergebnisse (in Durchläufen/s):

gcc, std::complex<double>: 1000
VS2003, std::complex<double>: 375
gcc, MyComplex: 320
VS2003, MyComplex: 290

Coda
2007-08-17, 00:59:59
Naja 2003 ist auch nicht der aktuellste Compiler. Beim 2005er wurde die STL auch nochmal gründlich überarbeitet.

DaEmpty
2007-08-17, 23:10:28
kann es vielleicht mit den mitgelieferten Bibliotheken zu tun haben?
Das zeigst du doch mit deinem Benchmark schon selbst.

gcc, std::complex<double>: 1000
VS2003, std::complex<double>: 375
gcc, MyComplex: 320
VS2003, MyComplex: 290
Das war aber hoffentlich höchstens gcc 3.3 mit den Bibliotheken von 2003.
Sonst ist es ein verdammt unfairer Test...