effizientes c++ auch ohne zeiger??
-
tester09 schrieb:
hallo , meine frage ist ganz einfach: Kann man in c++ auch gute, effiziente programme schreiben, und auf zeiger komplett verzichten? Also ohne dynamische speichereservierung, usw?
Wenn das Programm statisch sein darf, natürlich. Wenn nicht, dann natürlich nicht. Ist doch eine ganz logische Schlussfolgerung. Entweder true oder false.
Und dynamsiche Speicherreservierung braucht man, wie der Begriff vermuten lässt, um einem Programm Dynamik zu verleihen. Wenn Dynamik keine Anforderung ist, geht das. Aber die meisten heutigen Anwendungen verlangen Dynamik.
-
Bulli schrieb:
Referenzen sind keine Zeiger. Sonst könnte man auch Zeiger benutzen, und Referenzen hätte man nicht "erfinden" brauchen.
Referenzen und C-Zeiger werden vom Compiler 1:1 auf Zeiger in Assembler umgesetzt - das Konzept, nämlich: die Adresse des eigentlich gemeinten Objekts zu speichern, ist dasselbe.
Die Wahrheit ist: man kommt außer in den einfachsten Fällen (elementare Datentypen oder bei zusammengesetzten Datentypen nur "call by value", ständiges Neu-Erzeugen von Objekten, sobald ein Objekt verändert wird ... usw.) in kaum einer Programmiersprache ohne Zeiger aus.
Es wäre auch Speicherplatzverschwendung - wieso sollte man größere Objekte bei der Übergabe als Funktionsargument ständig kopieren, anstatt einen Zeiger auf das vorhandene Objekt zu übergeben ?
Selbst in Javascript, eine Sprache, die im Gegensatz zu C/C++ "weit vom Silizium entfernt" ist, werden nicht-elementare Datentypen "by reference" zugewiesen, also über Zeiger.
Zeiger sind ein derart fundamentales Konzept, daß nur wenige Anwendungsfälle denkbar sind, in denen man "komplett ohne" auskommt. Vielleicht in einigen Termersetzungssprachen oder Makrosprachen, aber definitiv nicht in C++ oder irgendeiner anderen gängigen komplexeren Sprache, die "call by reference" und komplexe Datentypen benutzen.
-
Die Implementieurng als Zeiger ist kein Muß. Für gewöhnlich sind Referenzen nur andere Namen für ein Objekt.
Die C++ Programmiersprache, Bjarne Stroustrup, 4. Auflage, Seite 105 schrieb:
Eine Referenz ist ein alternativer Name für ein Obejkt.
Das ein Compiler manchmal einen Zeiger draus macht, ist entweder eine Schwäche oder in der Situation vielleicht unumgänglich. Per Spezifikation ist eine Referenz aber kein Zeiger.
int i=0; int &a = i; a++;Jetzt willst du mir erzählen, das a ein Pointer ist? Wenn das ein Compiler macht, sollte man den Compiler verbessern!
Die C++ Programmiersprache, Bjarne Stroustrup, 4. Auflage, Seite 106 schrieb:
In einigen Fällen kann ein Compiler eine Referenz wegoptimieren, so daß es zur Lauftzeit kein Objekt gibt, das die Referenz repräsentiert.
Es dürfte damit klar sein, das die pauschale Aussage, das eine Referenz einfach nur ein Pointer ist, falsch ist.
-
in Deinem Beispiel ist int ein elementarer Datentyp, das ist nun gerade eine Ausnahmesituation, die ich in meinem Posting mehrfach ausgenommen hatte - der Compiler wird die Referenz wohl wegoptimieren. Na und ?
In den meisten Fällen hat man es mit komplexen Datentypen zu tun, und dann ist Zeiger und Referenz Jacke wie Hose.
An meiner Aussage ändert das nichts - in fast allen Anwendungsfällen und in den meisten Programmiersprachen kann man nicht auf das Konzept "Zeiger" verzichten, egal wie man das nennt und egal, wie es in der jeweiligen Sprache syntaktisch realisiert sein mag.
Auf Zeiger zu verzichten hieße ständiges Kopieren und Neu-Erzeugen von Objekten, was auf die Dauer den Speicher zumüllt und außerdem Zeit verschwendet.
-
@u_ser-l,
Toll, dann ist das ganze Programm ein Zeiger, denn jedes Programm und jeder Speicher des Programmes muss auf den Hauptspeicher. Und der Hauptspeicher wird über Zeiger angesprochen. Daher ist deine Aussage nicht wirklich sinnvoll.In der Ebene von C++ ist eine Referenz jedenfalls kein Zeiger. Und wir reden hier schliesslich in der Ebene von C++ und nicht in der Ebene des Hauptspeichers oder der CPU.
Grüssli
-
Bulli schrieb:
Sonst könnte man auch Zeiger benutzen, und Referenzen hätte man nicht "erfinden" brauchen.
hätte man auch nicht. egal ob es zeiger oder 'referenzen' gibt. durch das eine wird das andere redundant.

-
u_ser-l schrieb:
in Deinem Beispiel ist int ein elementarer Datentyp, das ist nun gerade eine Ausnahmesituation, die ich in meinem Posting mehrfach ausgenommen hatte - der Compiler wird die Referenz wohl wegoptimieren. Na und ?
In den meisten Fällen hat man es mit komplexen Datentypen zu tun, und dann ist Zeiger und Referenz Jacke wie Hose.
Nein, das trifft auch auf komplexe Objekte zu. In C++ gibt es keinen Unterschied zwischen elementaren Datentypen und komplexen Typen. Deshalb schreibt BS auch von "Objekten", da in C++ alles Objekte sind... auch
ints. Schließlich kann ich das machen:int *i = new int; string *s = new string; int i; string s;Das trifft dann natürlich auch auf Referenzen zu!
string s("Hallo"); string &a = s; a += " Welt!"; // wird an s angehängt!u_ser-l schrieb:
An meiner Aussage ändert das nichts -
Schön, du kannst gerne deine Aussage behalten. Nur leider glaube ich eher dem C++-Erfinder, als einem Unreg-User wie Dir.
u_ser-l schrieb:
Auf Zeiger zu verzichten hieße ständiges Kopieren und Neu-Erzeugen von Objekten, was auf die Dauer den Speicher zumüllt und außerdem Zeit verschwendet.
Wer sagt denn das immer was kopiert wird? Wird es ebend nicht, mit dem Konzept des Alias! (alternativer Name für ein Objekt)
-
langsam geht mir die Wortklauberei auf die Referenz.. äh, auf den Zeiger

Also gut, ich habe mich offenbar unklar ausgedrückt:
Außer in einfachen Fällen oder Sonderfällen (Referenzen nur zur Umbenennung von Variablen, Funktionen nur call-by-value, ...) ist es nicht möglich, in C++ auf Zeiger zu verzichten, sei es explizit (*,&-Operator) oder implizit (Referenz).
Nun zur Frage Zeiger!=Referenz: Wenn man Referenzen so wie Du verwendet, also nur zur Umbenennung einer Variable, dann kann der Compiler dies sicherlich wegoptimieren, und einen Zeiger oder ein int oder was auch immer für beides benutzen, Ok. In Deinem Fall ist die Benutzung der Referenz überflüssig, ein i++ hätte es auch getan.
Ein Beispiel, in denen ein Sprachfeature redundant angewendet wird, ist aber auch nicht gerade optimal zur Erläuterung gerade dieses Sprachfeatures.
Anwendungen von Referenzen in nichttrivialen Zusammenhängen, etwa als Funtionsparameter wie in
void foo(bar& aBar)werden wiederum als Zeiger realisiert. Und da ist dann nichts mehr wegzuoptimieren, wenn aBar in der Funktion foo verändert werden muß: Es wird ein Zeiger übergeben, auch wenn dieser auf syntaktischer Ebene "Referenz" heißt.
Abgesehen davon wird es kein Zufall sein, daß Referenzen als "implizite Zeiger" bezeichnet werden.
Mein Fazit:
Der Fragesteller fragte, ob es möglich ist, in C++ *komplett* auf Zeiger zu verzichten, nicht nur auf *syntaktischer* Ebene. Dieses ist in den meisten Anwendungsfällen zu verneinen. Man bekäme nicht einmal ein File mit einem Namen als char* geöffnet, man könnte keine Funktionen definieren, die ihre Argumente manipulieren, usw.
Beispiele für Sprachen, die ohne Zeiger auskommen, wären wohl einige sehr frühe BASIC-Dialekte, in denen keine Funktionen definiert werden können, keine Arrays existieren und die nur mit LET, REM, GOTO, GOSUB, PRINT, END und ein paar weiteren Befehlen auskommen. Denkbar wären auch Makro- oder Termersetzungssprachen.
-

-
~fricky schrieb:
Bulli schrieb:
Sonst könnte man auch Zeiger benutzen, und Referenzen hätte man nicht "erfinden" brauchen.
hätte man auch nicht. egal ob es zeiger oder 'referenzen' gibt. durch das eine wird das andere redundant.

Aber nur aus deiner Java-Sicht (wo diese sogenannten Referenzen nichts mit den C++-Referenzen zu tun haben), mein Lieber

Referenzen sind tatsächlich nur andere Namen. Das tolle an den Dingern ist, dass man damit dem Compiler explizit sagt: „Hömma Jung, da kannste einiges wegoptimieren.“
Und @user_l, wenn jemand anderes in seinem Code für die Implementierung der von mir genannten Objekte Zeiger verwendet, soll er doch ;). Ich muss es jedenfalls nicht tun, das war der Kern meiner Aussage. Man abstrahiert sich quasi den Teil der Zeiger, den man benötigt (Referenzierung bei Referenzen (genial, wa? ;)), Laufen über den Speicher bei Iteratoren, Anlegen der Daten auf dem Heap bei Smart Pointern) heraus und benutzt nur diesen.
u_ser-l schrieb:
Nun zur Frage Zeiger!=Referenz: Wenn man Referenzen so wie Du verwendet, also nur zur Umbenennung einer Variable, dann kann der Compiler dies sicherlich wegoptimieren, und einen Zeiger oder ein int oder was auch immer für beides benutzen, Ok. In Deinem Fall ist die Benutzung der Referenz überflüssig, ein i++ hätte es auch getan.
Es war ja auch nur ein einfaches Beispiel. Variablennamen wie
crazy_gen_func(palim).member().varkürzt man sich schon ganz gerne ab (auch, damit man den Kram weder mehrmals ausrechnen noch kopieren muss).u_ser-l schrieb:
Anwendungen von Referenzen in nichttrivialen Zusammenhängen, etwa als Funtionsparameter wie in
void foo(bar& aBar)werden wiederum als Zeiger realisiert. Und da ist dann nichts mehr wegzuoptimieren, wenn aBar in der Funktion foo verändert werden muß: Es wird ein Zeiger übergeben, auch wenn dieser auf syntaktischer Ebene "Referenz" heißt.
Da ist aber sowas von zu optimieren. Schonmal von Inlining gehört? Mal abgesehen davon, starte mal gdb mit einem beliebigen simplen Programm und schau, wie oft da steht
parameter optimized out.u_ser-l schrieb:
Abgesehen davon wird es kein Zufall sein, daß Referenzen als "implizite Zeiger" bezeichnet werden.
Werden sie? Hab ich noch nie gehört.
u_ser-l schrieb:
Der Fragesteller fragte, ob es möglich ist, in C++ *komplett* auf Zeiger zu verzichten, nicht nur auf *syntaktischer* Ebene. Dieses ist in den meisten Anwendungsfällen zu verneinen. Man bekäme nicht einmal ein File mit einem Namen als char* geöffnet, man könnte keine Funktionen definieren, die ihre Argumente manipulieren, usw.
Referenzen sind keine Zeiger, Arrays auch nicht.
Abgesehen von dem ganzen Kram fehlt das einzige, wo man wirklich einen Zeiger verwenden muss, weil es im Sprachstandard verankert ist. Denk mal an Klassen, in deren Methoden das eigene Objekt einer Funktion übergeben werden soll

-
@bulli:
gOo0gle Suche nach:
c++-faq-lite referencesund dann nachlesen unter "Underneath it all ..."
Referenzen sind eben kein anderes Konzept als Zeiger, sie heißen nur anders und haben eine andere Syntax.
-
Bei...
int a = 3; int &b = a;...wird doch keine Zeigervariable angelegt. Der Compiler sieht b als a.
Also nix Zeiger.
-
u_ser-l schrieb:
Referenzen sind eben kein anderes Konzept als Zeiger, sie heißen nur anders und haben eine andere Syntax.
Genau, das macht Sinn!

-
The nitpicking feast is open.

-
nach Eurer Argumentation müßte dann 0x10+0x1 etwas Anderes sein als 16+1.
Der Compiler macht aber aus beidem dasselbe add.
"andere Syntax => anderes Konzept" gilt eben nicht immer, besonders nicht in einer Syntaxregel-reichhaltigen Sprache wie C++, wo mehrfach dasselbe Konzept in verschiedene Syntax eingekleidet ist. printf und cout << ist ja auch nicht wirklich etwas Anderes, obwohl die Syntax verschieden ist.
-
C++ Ebene != CPU Ebene
Ich kann mich nur wiederholen. Wenn du es von der Hardware aus anschaust, vom kompilierten Code her, dann kann man nicht auf Zeiger verzichten, das ist korrekt. Aber dem Threadersteller ging es um die Zeiger in C++, also der Programmiersprache C++ und nicht das was nach dem Kompilieren herauskommt. Und wenn wir auf der Ebene von C++ bleiben, dann kann man auf Zeiger verzichten und dann sind Referenzen keine Zeiger. Punkt und aus.
Grüssli
-
u_ser-l schrieb:
nach Eurer Argumentation müßte dann 0x10+0x1 etwas Anderes sein als 16+1.
Man kann auch Worte nach belieben im Munde herumdrehen. Fakt ist, das Referenzen keine Zeiger sein müssen, und in der Praxis auch je nach Compiler/Optimierung nicht sind.
Wenn ich schreibe:
int a = 1;
int * b = &a;erwarte ich das zwei Speicherbereiche belegt werden (Einmal der Wert, einmal die Adresse).
Im Falle von:
int a = 1;
int & b = a;Ist es aber voraussichtlich nur ein Speicherbereich (Der Wert), der im Programmcode über zwei Namen angesprochen werden kann.
cu André
-
Dravere schrieb:
Aber dem Threadersteller ging es um die Zeiger in C++, also der Programmiersprache C++ und nicht das was nach dem Kompilieren herauskommt.
Der TE sagte aber "... komplett auf Zeiger verzichten" und nicht: "... auf * und & verzichten".
Dravere schrieb:
Und wenn wir auf der Ebene von C++ bleiben, dann kann man auf Zeiger verzichten
und wie öffnest Du in C++ ein File ohne char* ?
Grüße
-
asc schrieb:
Im Falle von:
int a = 1;
int & b = a;Ist es aber voraussichtlich nur ein Speicherbereich (Der Wert), der im Programmcode über zwei Namen angesprochen werden kann.
ja, das ist eine syntaktische Sache, die auf der Maschinenebene wahrscheinlich nicht abgebildet wird. Das hatten wir doch schon.
Erinnert etwas an Hütchenspielerei - ein Syntaxkonstrukt veranschaulichen mit einem Beispiel, bei dem der Compiler just dieses Konstrukt ins Nichts wegoptimiert.
Bei
void foo(bar& aBar)kann der Compiler aber nicht wegoptimieren und übergibt einen Zeiger.
Wir streiten uns hier über ein syntaktisches Konstrukt "&", das in C++ mehrere verschiedene Bedeutungen hat - u.a. Umbenennung von Variablen, Referenzparameter, ...
Ehrlich gesagt, hätte ich jetzt lieber einen freien Rest-Sonntag, ciao.
-
Ja, der TE sollte mal genauer formulieren...
u_ser-l schrieb:
und wie öffnest Du in C++ ein File ohne char* ?
Nicht die C++ -STDLib nutzen.