effizientes c++ auch ohne zeiger??



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


  • Administrator

    u_ser-l schrieb:

    Der TE sagte aber "... komplett auf Zeiger verzichten" und nicht: "... auf * und & verzichten".

    Du solltest mal die Beschreibung dieses Forums lesen. Wir sind hier im C++ Forum, also der Programmiersprache C++. Wenn hier jemand "komplett auf Zeiger verzichten" schreibt, dann nehme ich logischerweise an, dass er damit meint, dass er auf die Zeiger in der Programmiersprache C++ verzichten will. Sonst ist er schlicht und einfach gesagt im falschen Forum!
    Es macht auch keinen Sinn, wieso jemand auf Zeiger verzichten möchte, welche ihn gar nicht stören, da er sie gar nie sieht ... :p

    u_ser-l schrieb:

    und wie öffnest Du in C++ ein File ohne char* ?

    std::string path;
    std::fstream file(path.c_str());
    

    Ich habe selber nie ein char const* verwendet! Konnte persönlich also vollständig darauf verzichten.
    Und im neuen Standard kann man ja dann auch sogar das folgende machen, falls du wirklich so ein Erbsenzähler bist:

    std::string path;
    std::fstream file(path);
    

    Grüssli



  • Dravere schrieb:

    Es macht auch keinen Sinn, wieso jemand auf Zeiger verzichten möchte, welche ihn gar nicht stören, da er sie gar nie sieht ... :p

    langsam verstehen wir uns 👍

    Das ist wie mit den bugs - man sieht sie nicht, und doch sind sie da.

    Jetzt aber schönen Sonntang noch.



  • @u_ser-l!
    Dann ist wohl a und b hier auch für dich das gleiche?

    int a = 100;
    int b = 0100;
    

    Nach deiner Argumentation sind beide gleich, da der Compiler daraus Dezimalwerte macht. Wo würden wr denn in Zukunft hinkommen, wenn eh alles angeblich gleich sein soll, nur weil am Ende im Speicher alles als Bits abgebildet wird. Weißt, mich als C++-Programmierer interessiert das was der COmpiler macht, nur zweitrangig. Wenn man mit anderen Menschen kommuniziert, muß man sich an Regeln halten. Und wir reden hier C++...



  • In C++ haben nun mal oft mehrere verschiedene Konzepte gleiche Syntaxelemente: '&' für Ref.Var., '&' für Ref.Parameter, '&' für 'und', '&' für ...
    ähnlich auch bei 'static', '>>' usw.

    - andererseits werden gelegentlich gleiche Konzepte durch verschiedene Syntaxelemente (z.B. Zeiger *und* Referenzen für die Argumentübergabe 'by reference') repräsentiert.

    Daß bei C++ keine eindeutige Zuordnung zwischen Konzepten und Syntaxelementen vorliegt, erschwert eine Diskussion wie diese hier.

    Aber das ist nun ein Thema, das nicht mehr in's "C++"-Forum gehört.



  • Ihr wisst schon dass Ihr alle total am Thema vorbei schreibt?
    Macht doch einfach einen Thread auf mit der Überschrift "sind Referenzen Zeiger?".

    Also zum Thema (und ich beziehe mich auf objektorientiertes Programmieren):
    - Streng genommen:
    Nein. Man kann so ja nichtmal this benutzen, denn this ist ein Zeiger. Oder wie schon genannt Arrays wie "hallo welt".

    - Nicht ganz so streng genommen:
    Teilweise. Ich versuche selber auf Zeiger zu verzichten. Mit oben genannten Ausnahmen natürlich. Der Grund liegt in stabileren Programmen, da die meisten Fehler von Nullzeigern oder Zeigern die auf falsche Stellen im Speicher weisen. Meine Erfahrung ist dass Referenzen bzw. einfach lokale Variablen oder Klassenvariablen zu *sehr* viel stabileren Programmen führen. Sowas bekommt man bei hoher Zeigernutzung nie hin. Arrays kann man übrigens in Vectoren oder ählichen Klassen ablegen. Sehr stabil und man weiß auch immer die Größe.
    Nur eines geht meines Wissens überhaupt nicht. Und zwar abgeleitete Klassen.
    Wenn man schreibt

    Abgeleiteteklasse c;
    Basisklasse b = c;

    dann hat man mit "b" nicht wie in Java z.B. ein Objekt vom Typ "Abgeleiteteklasse". Das ist richtig übel. Man muß in dem Fall mit Zeigern arbeiten. Auch Referenzen bringen einen nicht weiter.
    Beispiel mit Zeiger:

    Abgeleiteteklasse c;
    Basisklasse * b = new Abgleiteteklasse(c);

    Das wäre dann korrekt. Man hätte so auch bei "b" den Typ "Abgleiteteklasse".
    Referenzen bringen einen hier auch nicht mehr weiter:

    Wenn man schreibt

    Abgeleiteteklasse c;
    Basisklasse b = c;

    dann hat man mit "b" nicht wie in Java z.B. ein Objekt vom Typ "Abgeleiteteklasse". Das ist richtig übel. Man muß in dem Fall mit Zeigern arbeiten. Auch Referenzen bringen einen nicht weiter.
    Beispiel mit Zeiger:

    Abgeleiteteklasse c;
    Basisklasse & b = c;

    Funktioniert zwar wenn einem ein Alias reicht. Aber wenn man das Objekt klonen will hilft einem nur noch ein "new" weiter.

    Oder gibt es eine Möglichkeit wie man das Problem ohne new lösen kann? Ich glaube aber nicht.



  • Sorry, ein Absatz ist doppelt. Keine Ahnung warum. Ich kann leider nicht editieren.
    Und weiter unten sollte es heißen "Beispiel mit Referenz". Leider steht da "Beispiel mit Zeiger".



  • Granini schrieb:

    Wenn man schreibt

    Abgeleiteteklasse c;
    Basisklasse b = c;

    dann hat man mit "b" nicht wie in Java z.B. ein Objekt vom Typ "Abgeleiteteklasse".

    Im Gegensatz zu C++ wo Referenzen unter gewissen Umständen nur ein Aliasname sind, ist in Java eine Referenz eindeutig ein Zeiger mit anderer Syntax (null ist Zulässig; Die Häufigste Exception die ich aus Javaprogrammen kenne ist die Nullpointer-Exception [oder wird sie NullReference genannt?]...). Zudem macht Java bei Objekten immer eine Referenzübergabe (Eine Änderung an einen übergebenen Objekt ändert das Orginal).

    In diesen Fall vertrete ich Ausnahmsweise mal die Linie von user_l.

    cu André
    P.S: Diese Null-Exception unter Java ist für mich auch einer der Beweise, warum man auch mit Sprachen wie Java und C# durchaus wissen sollte was man macht... 😉



  • Granini schrieb:

    Funktioniert zwar wenn einem ein Alias reicht. Aber wenn man das Objekt klonen will hilft einem nur noch ein "new" weiter.

    Oder gibt es eine Möglichkeit wie man das Problem ohne new lösen kann? Ich glaube aber nicht.

    Wenn du Polymorphie brauchst und ein Objekt kopieren willst, ist new schon naheliegend. Falls dir aber das Aufräumen zu mühsam ist, kannst du Smart Pointers verwenden. Und immer schön dran denken, Destruktor virtuell zu machen. 😉

    Aber Zeiger gehören nun mal zu C++. Wenn man sich für diese Programmiersprache entscheidet, nimmt man auch die Zeiger in Kauf. Sie bieten einem ausserdem sehr viele Möglichkeiten, auch wenn sie fehleranfällig sind. Man muss sie halt nicht exzessiv einsetzen, sondern wo möglich auf Container, Smart Pointer und andere Hilfsmittel ausweichen.



  • Ich könnte mir keine Programmierwelt ohne Zeiger vorstellen. Und damit meine ich auch die Fälle, in denen ich zwar selber keine benutze, aber weiß, dass die Klassen, die ich verwende, diese benutzen. Für mich würde es auch keinen Unterschied machen, wenn die Klassen zwar soetwas nicht betreiben würden, aber dafür die "Sprache" im Hintergrund. Ohne geht es einfach nicht. Nirgendwo. Man sollte aber bestrebt sein, die Verwendung von Zeigern so oft wie möglich gut getesteten Bibliotheken (oder halt "Sprachen") zu überlassen oder einfach keine Fehler machen 😉
    Ich denke, dass der TE auch eher wieder einen kleinen Krieg auslösen wollte, aber ich bin grad etwas angeschwipst, von daher lässt mich das kalt 🙂



  • Decimad schrieb:

    Ich denke, dass der TE auch eher wieder einen kleinen Krieg auslösen wollte, aber ich bin grad etwas angeschwipst, von daher lässt mich das kalt 🙂

    😮
    Es ist Montag Abend!?!

    Ich will gar nicht wissen, wie du Freitags drauf bist.. 😉



  • Dafür hab ich am Wochenende gewerkelt, ich bin da flexibel bei der Wahl des Abends, an dem ich mich mal gehen lasse 🙂



  • u_ser-l schrieb:

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

    Auf der Ebene ist ALLES ein Zeiger. In ASM werden schließlich immer irgendwelche Speicheradressen herumgereicht und dahin entweder gelesen, geschrieben oder dahingesprungen....

    Ich glaube nicht, dass ein derart philosophischer Ansatz vom OP gemeint ist, sondern dass er gerne Programme ohne new/delete (und ggf. ohne array-Zeigerarithmetik) schreiben möchte - und das ist sehr wohl möglich und sogar erstmal die Standardherangehensweise.

    Gruß,

    Simon2.



  • u_ser-l schrieb:

    ...blablabla...

    Nuchts für ungut, aber durch das gebetsmühlenartige Wiederholen von von Falschaussagen, werden keine richtigen Aussagen daraus.

    1. )Der Standard schreibt nicht vor, ob eine Referenz Speicher belegt, oder nicht. Das heisst, der Standard schreibt auch nicht vor, ob sich hinter einer Referenz ein Zeiger verbirgt, oder nicht. Nur, weil viele Compiler es so machen, ist die Aussage Referenz==Zeiger trotzdem falsch. Deine Aussage ist, dass Referenzen 1:1 in Zeiger umgesetzt werden, ist damit ebenfalls falsch. Dies ist weder für triviale noch für komplexe Objekte zwangsläufig der Fall.
    2. )Referenzen müssen an valide Objekte gebunden sein, da sie ein )Aliasname für diese Objekte darstellen. Bei Zeigern ist das nicht der Fall.
    3. )Referenzen erlauben keine Zeigerarithmetik.
    4. )Referenzen dürfen keine Referenzen referenzieren. Ebensowenig dürfen Zeiger auf Referenzen zeigen. Man kann auch keine Arrays aus Referenzen bilden. Grund: siehe Punkt a.)

    Simon2 schrieb:

    Auf der Ebene ist ALLES ein Zeiger. In ASM werden schließlich immer irgendwelche Speicheradressen herumgereicht und dahin entweder gelesen, geschrieben oder dahingesprungen....

    Stimmt auch nicht. Operationen auf Registern haben nichts mit Zeigern zu tun, sondern entsprechen dem Arbeiten mit Variablen.

    Zum TO:
    Es gibt, und das wurde ja auch schon gesagt, keinen Grund, Zeiger komplett zu vermeiden. Man sollte Zeiger dort einsetzen, wo es sinnvoll ist. Allerdings kann man durch die konsequente Benutzung von Referenzen und Containern Zeiger weitgehend vermeiden.

    Edit: Zeiger -> Referenzen (danke an asc).



  • Tachyon schrieb:

    [*]Zeiger müssen an valide Objekte gebunden sein, da sie ein Aliasname für diese Objekte darstellen. Bei Zeigern ist das nicht der Fall.

    Korrektur: "Referenzen" müssen...

    Ansonsten gebe ich dir aber Recht. Mir ist - so fern es für die Verwendung unerheblich ist - auch egal, wie Compiler irgendetwas umsetzen.

    cu André



  • Tachyon schrieb:

    ...

    Simon2 schrieb:

    Auf der Ebene ist ALLES ein Zeiger. In ASM werden schließlich immer irgendwelche Speicheradressen herumgereicht und dahin entweder gelesen, geschrieben oder dahingesprungen....

    Stimmt auch nicht. Operationen auf Registern haben nichts mit Zeigern zu tun, sondern entsprechen dem Arbeiten mit Variablen.
    ...

    OK, meine ASM-Kenntnisse sind recht eingerostet.
    Aber wieviel kann man denn überhaupt in Registern machen? Und muss man die nicht auch vorher (eben über einen "Zeiger") aus dem Speicher laden (zumindestens initial)?

    Gruß,

    Simon2.



  • Simon2 schrieb:

    OK, meine ASM-Kenntnisse sind recht eingerostet.
    Aber wieviel kann man denn überhaupt in Registern machen? Und muss man die nicht auch vorher (eben über einen "Zeiger") aus dem Speicher laden (zumindestens initial)?

    Gruß,

    Simon2.

    Laden muss man schon irgendwie, aber für Arithmetik etc. braucht man keine Zeiger. Und Literale werden i.d.R. auch direkt geladen.



  • Tachyon schrieb:

    ...
    Laden muss man schon irgendwie, aber für Arithmetik etc. braucht man keine Zeiger. Und Literale werden i.d.R. auch direkt geladen.

    Gut zu wissen.
    Ich bin aber auch eher von "Objekthandling" ausgegangen und nicht nur von nativen Zahlen und Strings. Und mehr als das "Laden" (sprich new/delete) hat der OP an pointerspezifischem Zeug auch nicht genannt.... 😉

    Nach meiner laienhaften Vermutung durchlaufen aktuelle Anwendungen zu 80% Operationen, die "Zeiger" verwenden....

    Aber letztlich ist das hier philosophisch und wir beide sind uns wohl einig darin, dass der Ansatz von "user-I" überzogen und wenig hilfreich ist.

    Gruß,

    Simon2.


Anmelden zum Antworten