C++ / Delphi



  • Wird das jetzt ein Warum-wurde-C++-erfolgreich?-Thread?

    Ne, aber wir streiften die Frage, warum Borland unbedingt Pascal objektorientiert machen musste anstatt gleich ADA zu nehmen.



  • Original erstellt von Daniel E.:...
    'concurrency' (vertändliche Übersetztung?)

    'Nebenläufigkeit' ist afaik gebräuchlich

    **
    ADA wurde ja mit anderen Motiven (Vereinheitlichung) entwickelt.
    **

    .. und hat mit Pascal nicht besonders viel zu tun, von banalen Oberflächlichkeiten (siehe früher in diesem Thread, Stichworte begin/end vs. {/}, :=/= vs. =/== etc ;)) abgesehen.



  • Original erstellt von kartoffelsack:
    **
    Die Ableitung von einem gemeinsamen Basisobjekt ist zwingend, wenn man mit Containern arbeiten will, in die man alle Objekte einbinden kann.

    Jede Klasse deren Objekte in diesem Container abgelegt werden können sollen, muss von einer gemeinsamen Basisklasse abgeleitet werden.
    **

    Warum nicht einfach Container, die TPointer (in C++: void*) enthalten?
    Man könnte genauso alle Objekte in dem Container unterbringen, und hätte
    eine Möglichkeit gefunden, gleichzeitig Mehrfachverebung zuzulassen.
    Oder steckt da ein Denkfehler drin?



  • Oder steckt da ein Denkfehler drin?

    Ja. 😉

    Das mit den Containern war nur ein Grund, das so zu machen. Man könnte das natürlich auch irgendwie mit void-Zeigern lösen. Der Punkt ist aber, dass durch die Gemeinsame Basisklasse jede Klasse eine gewisse Mindestanforderung erfüllt. Welche auch immer das sein mag (mir fällt kein wirklich gutes ein 😉 ).



  • Original erstellt von Bashar:
    Inwiefern stellt das eigentlich, wie hier von einigen vertreten, einen Nachteil dar?

    Öhm, Speicherverschwendung vielleicht, da jedes Objekt - von welcher Klasse auch immer - die Eigenschaften, Methoden und Members(intern) von TObject erbt. Und was ist, wenn ich die garnicht brauche, was z.B. bei einer Klasse für komplexe Zahlen durchaus der Fall währe? Für mich ist das ein Nachteil.



  • hm, sollte der Compiler nicht in der Lage sein, geerbte Members, die nicht benötigt werden wegzuoptimieren?



  • Ich hoffe doch sehr dass TObject keine Datenmembers hat, sonst würde das ganze in der Tat schon leicht in Richtung Schwachsinn gehen ...



  • hat es auch nicht (glaub ich zumindest)



  • OK, hab grad mal nachgeschaut. TObject hat tatsächlich nur Methoden - keine Members.



  • Dann will ich mal die Diskussion wieder anheizen *g*. Da ich sowohl mit Delphi als auch mit C++ mehrere Jahre meine Brötchen verdient habe, bilde ich mir ein, dass ich meinen Senf dazugeben kann.
    Die Äußerungen von kartoffelsack gefallen mir prinzipiell ganz gut, auch wenn ich in einzelnen Punkten nicht ganz zustimmen kann.
    Was meinst Du mit der „automatische Destruktion von Objekten“? Meinst Du damit, dass am Ende des Scopes ein Objekt automatisch freigegeben wird, wenn dieses nicht dynamisch angefordert wurde oder gibt es in C++ etwas, was mir all die Jahre verborgen geblieben ist?
    In Delphi kann man sich das try finally sparen, wenn man sich die Mühe macht mit Interfaces zu arbeiten. Man muss einfach im Einzelfall entscheiden, ob sich der Aufwand lohnt.
    Weiterhin gibt es in Object Pascal nicht nur „class“ sondern auch „object“. Das ist ein Überbleibsel aus Turbo Pascal 5.5-Zeiten. Derartige Klasen verhalten sich ähnlich wie C++-Klassen. Man kann also nicht nur dynamisch eine Instanz erzeugen, sondern auch eine, die autom. am Anfang der Methode erzeugt und am Schluss wieder freigegeben wird. „object“ wird aber normalerweise von Delphi-Programmierern nicht verwendet.
    Bei Delphi für .NET ist dann auch zwangsweise Garbage Collection mit dabei.

    Es stimmt, dass Delphi zu den Templates nichts vergleichbares hat. Ich persönlich mag Templates aber nicht besonders.
    Template-Code lässt sich IMHO sehr schwer lesen.
    Durch Templatecode zu debuggen ist ein Drama. Ich weiß meistens nicht einmal in welcher Klasse ich mich gerade befinde. Wenn man bei Parametern mit STL-Klassen arbeitet muss man sich immer erst durch etliche Zeilen STL-Code quälen, bevor man in der Methode landet, die man eigentlich debuggen will.
    Und was ich am meisten an den Templates hasse, ist dass sie die Übersetzungszeit endgültig in den Keller abgehen lassen.
    Die Typsicherheit von Templates bekomme ich bei Delphi dadurch, dass ich das von Hand mache, was bei Templates vom Compiler erledigt wird. Ich kopiere den ganzen Code einer speziell geschriebenen Klasse und lasse durch suchen/ersetzen den Typ einsetzen. Das kostet mich zwar etwas Zeit beim Tippen, die bekomme ich aber wieder um ein vielfaches zurück, dadurch, dass sich der Code besser lesen, debuggen und viel schneller übersetzen lässt.

    Es wurde hier geäußert, dass sich C++ bei großen Projekten besser eignen würde als Delphi. Ich bin genau anderer Meinung. C++ hat gegenüber ObjectPascal etliche Vorteile, aber unter dem Strich steht bei mir ObjectPascal klar vor C++. Mit Delphi lassen sich große Projekte viel schneller entwickeln als z.B. mit dem C++Builder.
    Bei großen Projekten arbeiten immer etliche Entwickler zusammen. Somit treffen auch mehrere Programmierstile aufeinander. Da C++ viel mehr Freiraum lässt, wie man es programmiert, steigt das Risiko, dass der eine Code produziert in dem sich der andere nur schwer zurecht findet.
    Ich habe momentan das Problem, dass ich jemanden einarbeiten muss, der aus der VB-Ecke kommt. In unserem Projekt wird aber fast alles verwendet, was C++ so hergibt. Es wäre sicherlich deutlich leichter für den Neuen sich in ein entspr. Delphi-Projekt einzuarbeiten.
    Bei C++-Compilern darf man nach Fehlern suchen, die ein Delphi-Programmierer nie zu sehen bekommt. Einer meiner Lieblinge ist „unresolved external“. Bei Delphi gibt es zwar auch eine Fehlermeldung, die in eine ähnliche Kerbe schlägt. Aber selbst die haben bestimmt die meisten Delphiprogrammierer noch nie zu sehen bekommen.
    Was aber am meisten Zeit kostet ist der langsame C++-Compiler. Wenn ich unser Projekt komplett übersetzen lassen muss, dann kann ich zwei Stunden (P4 mit 1,5GHz) lang etwas anderes tun. Ich habe eine Unit (C++Builder) die sage und schreibe alleine über drei Minuten zum übersetzen braucht. Mal schnell etwas ausprobieren kann man da komplett vergessen. Ich habe etliche Stunden/Tage nur damit verbracht, mir zu überlegen, wie ich den Code umstrukturiere, damit die Übersetzungszeiten besser werden. Zu allem Überfluss kommen mit dem VisiBroker (CORBA) noch Headerdateien dazu, die ich nicht in die vorcompilierten Headerdateien mit aufnehmen kann, da diese sonst gar nicht erzeugt werden.
    Als ich vor etlichen Jahren ein ähnlich großes Projekt mit Delphi umgesetzt habe, hat selbst das komplette erzeugen nur knapp über eine Minute (Pentium II 350 MHz) gedauert.

    Es macht keinen Spaß ständig auf den C++-Compiler warten zu müssen.

    Die Diskussionen über Schleifen, begin/end, oder über den Sinn/Unsinn dass alle Klassen von TObject abgeleitet sein müssen, ist in meinem Augen Kleinkram, der nicht wirklich Einfluss darauf haben sollte, für welche Sprache/Entwicklungsumgebung man sich entscheidet.



  • Was meinst Du mit der ?automatische Destruktion von Objekten?? Meinst Du damit, dass am Ende des Scopes ein Objekt automatisch freigegeben wird, wenn dieses nicht dynamisch angefordert wurde oder gibt es in C++ etwas, was mir all die Jahre verborgen geblieben ist?

    Damit mein ich, dass man alles, was unbedingt getan werden muss in einen Destruktor reinpackt und damit sicherstellt, dass es ausgeführt wird - bei einer Exception genauso wie im normalen Programmfluss.
    Anwendungsbeispiel: SmartPointer. Wenn die letzte Referenz eines Pointers die Gültigkeit verliert, wird der Speicher freigegeben.
    Dieses Prizip (Resource Aquiration is initialisation = RAII) kann man aber auf alle Arten von Resourcen Anwenden, wodurch es einer Garbage-Collection überlegen ist.

    Der C++Builder ist übrigens ganz besonders übel in sachen Compile-Zeit. Bei anderen Compilern is das nicht so extrem. Leider haben die andere Nachteile 😞 🙄



  • Original erstellt von Eisenherz:
    Mal schnell etwas ausprobieren kann man da komplett vergessen.

    Das hat mit ernsthaftem Programmieren sowieso nichts zu tun.

    Original erstellt von kartoffelsack:
    Dieses Prizip (Resource Aquiration is initialisation = RAII) kann man aber auf alle Arten von Resourcen Anwenden, wodurch es einer Garbage-Collection überlegen ist.

    Für sinnlose Definitionen von 'alle' vielleicht ... RAII funktioniert bei Ressourcen nicht, wo beim Schließen Fehler auftreten können.

    Und wie kann ein Programmierstil einer Technik überlegen sein (oder umgekehrt) und was spricht dagegen, es zu kombinieren? WIMRE machen es einige ADA-Umgebungen genau so.

    Manche Sprachen haben andere interessante Ansätze bezüglich des Ressourcenmanagement entwickelt, z.B. Lisp oder Ruby. Andere Sprachen bieten hier nichts brauchbares (Java).



  • Original erstellt von kartoffelsack:
    SmartPointer. Wenn die letzte Referenz eines Pointers die Gültigkeit verliert, wird der Speicher freigegeben.

    SmartPointer sind etwas, was ich wirklich mag. So klein die Klasse ist, so ist sie für mich eines der besten Beispiele für die sinnvolle Anwendung von Templates und dem Überladen von Operatoren.
    In Delphi bilde ich SmartPointer wie schon angedeutet mit "interface" nach, da diese auch Referenzen zählen und sich "selbst" freigeben. Um sich Tipparbeit zu sparen gibt es "with", wobei ich persönlich "with" nicht sonderlich mag.

    Der C++Builder ist übrigens ganz besonders übel in sachen Compile-Zeit. Bei anderen Compilern is das nicht so extrem. Leider haben die andere Nachteile 😞 🙄

    Toll finde ich dass der C++Builder beim Übersetzen nur ca. 7 Prozent des Prozessors belegt. Wie schnell könnte er sein, wenn er wirklich den ganzen Prozessor nutzen würde.
    Wenn man nicht aus der Entwicklungsumgebung heraus übersetzt, sondern über Batch-Dateien, dann soll er angeblich bis zu dreimal so schnell sein.



  • Original erstellt von Daniel E.:
    Das hat mit ernsthaftem Programmieren sowieso nichts zu tun.

    Heißt das, dass ein "ernsthafter" Programmierer immer über alles genau Bescheid weiß, jeden Hilfetext vollständig versteht und nie durch ausprobieren herausfinden muss, was ihm dieser Hilfetext genau sagen will oder wie z.B. bestimmte Effekte an der Oberfläche wirken?

    Dann werde ich nie ein "ernsthafter" Programmierer werden.

    [ Dieser Beitrag wurde am 08.01.2003 um 16:49 Uhr von Eisenherz editiert. ]



  • Ich hatte mehr an etwas wie '-Probier mal da ne 3 statt 2! -Geht nicht! -Probier 'ne 4!' gedacht ;).
    Auf einer halbwegs fundierten Grundlage etwas zu probieren ist okay, auch wenn ich dafür keinen offiziellen Code benutzten würde ... YMMV.



  • Original erstellt von kingruedi:
    Also wenn ich all das glaube, was mir Bashar von ADA erzählt hat, frag ich mich, warum die kein ADA Builder 😉 entwickelt haben

    Nur einige Ergänzungen zu Ada:
    Diese Programmiersprache wurde nicht nur Zwecks Vereinheitlichung (das DoD hatte ganz schön Chaos..) entwickelt, sondern besonders für bessere Wiederverwendbarkeit, Selbstdokumentation, Laufzeit-Sicherheit und Portabilität
    (jeder validierter Ada95-Compiler musste einen Test bestehen)
    Kingruedis Frage ist berechtigt, aber leider gewinnt nicht immer der Beste...
    Die Firma Aonix entwickelt übrigens genau das... ObjectAda nennt sich das Teil.
    ..
    last but not least: Ada ist ein Name, keine Abkürzung, dafür würden euch die
    Jungs unter comp.lang.ada einen Kopf kürzen 😉



  • Toll finde ich dass der C++Builder beim Übersetzen nur ca. 7 Prozent des Prozessors belegt. Wie schnell könnte er sein, wenn er wirklich den ganzen Prozessor nutzen würde.

    Also mein C-Builder belegt > 90% und braucht trotzdem ewig. Hast Du die Hintergrund-Compilierung an? Damit ist er nämlich NOCH langsamer.

    Weiterhin gibt es in Object Pascal nicht nur ?class? sondern auch ?object?. Das ist ein Überbleibsel aus Turbo Pascal 5.5-Zeiten. Derartige Klasen verhalten sich ähnlich wie C++-Klassen. Man kann also nicht nur dynamisch eine Instanz erzeugen, sondern auch eine, die autom. am Anfang der Methode erzeugt und am Schluss wieder freigegeben wird

    Soweit ich mich entsinne müssen aber Ctor und Dtor trotzdem explizit aufgerufen werden. Das ist ja der springende Punkt.

    [ Dieser Beitrag wurde am 08.01.2003 um 18:58 Uhr von kartoffelsack editiert. ]



  • Lesbarkeit:
    OPascal kann man wirklich schneller lesen teilweise, aber was mich stört
    Funktionsaufrufe müssen keine () bei leerer Parameter Liste haben 😞
    und das der Typ einer Funktion erst am Ende kommt

    function lala(foobar : Integer) : Real;
    

    Aber ich finde C++ ist auch leicht zu lesen, wenn man sich dran gewöhnt. Templates können aber wirklich Funktionen unübersichtlich machen, aber das ist auch Gewöhnungssache IMHO

    ADA:
    Ich dachte immer, dass ADA eine Verbesserung (deutliche!) von Pascal ist, sozusagen inc(Pascal)

    Compilezeit:
    zur Compilezeit Minimierung sind die Systeme sehr praktisch, die das compilieren auf verschiedene Rechner aufteilen, ähnlich nach dem SETI@Home Prinzip, ich weiss aber nicht, ob es so was für Windows gibt. Aber für mal eben ausprobieren alles neuzukompilieren ist ein bisschen übertrieben, ist es nicht? (man kann natürlich pech haben und probiert mal so ein bisschen an wichtigen Stellen rum und man kommt nicht mehr an "Alles Neuerstellen" vorbei, aber an den Basis stellen sollte man eh lieber am Anfang rumfummeln ;))



  • Original erstellt von kingruedi:
    **
    ADA:
    Ich dachte immer, dass ADA eine Verbesserung (deutliche!) von Pascal ist, sozusagen inc(Pascal)**

    Wer von Pascal auf Ada (watch the spelling) umsteigt, verbessert sich tatsächlich deutlich 😉
    Dass einige Ideen von Pascal auf Ada übernommen wurden, sieht man am Syntax
    recht schnell.... aber trotzdem ist Ada keine "Weiterentwicklung", sondern vielmehr eine komplette Neuentwicklung mit bestimmten Vorgaben...



  • Original erstellt von kartoffelsack:
    **Also mein C-Builder belegt > 90% und braucht trotzdem ewig. Hast Du die Hintergrund-Compilierung an? Damit ist er nämlich NOCH langsamer.
    **

    Ich hatte bis vor kurzem sogar 100 Prozent. Dann habe ich die Unterstützung des DMA-Transfers vom Betriebssystem aktiviert. Seit dem braucht er nur noch ca 7 Prozent. An den Übersetzungszeiten selbst hat das aber nichts geändert. Bei mir macht es auch keinen Unterschied, ob ich die Hintergrund-Compilierung an habe.
    Wir haben ein paar Leute von Borland im Haus. Die konnten mir das aber auch nicht erklären.

    Soweit ich mich entsinne müssen aber Ctor und Dtor trotzdem explizit aufgerufen werden. Das ist ja der springende Punkt.

    Ich muss gestehen, dass ich seit Borland Pascal 7 nicht mehr damit gearbeitet habe und ich mich deswegen evtl. falsch erinnere. Ich bin jetzt aber zu faul dem weiter nachzugehen.

    [ Dieser Beitrag wurde am 09.01.2003 um 17:35 Uhr von Eisenherz editiert. ]

    [ Dieser Beitrag wurde am 09.01.2003 um 17:36 Uhr von Eisenherz editiert. ]


Anmelden zum Antworten