private bleibt wirkungslos
-
Wenn da so
:const Rational operator*(const Rational& lhs, const Rational& rhs);
-
Freak_Coder schrieb:
Wenn da so
:const Rational operator*(const Rational& lhs, const Rational& rhs);Begründung?
-
Freak_Coder schrieb:
Wenn da so
:const Rational operator*(const Rational& lhs, const Rational& rhs);Durchaus möglich, mache ich meistens auch so. Ist aber keinesfalls zwingend. Genauso wenig wie die Argumente per Referenz zu übergeben. Alexandrescu hat zB mal was dazu geschrieben. Es ging hier ja lediglich um das Prinzip zwischen Klassen- und Namensraumüberladung von binären Operatoren. Die letztendliche Implementation hängt sowieso vom jeweiligen Szenario ab.
-
groovemaster schrieb:
Soweit müsste man gar nicht gehen. Private/protected Zugriff auf Objektebene würde in C++ nur Sinn machen, wenn man prüft, ob ein Member zu this gehört oder nicht. In deinem Fall gehört foo_ zu r und müsste somit einen Compilerfehler verursachen. Die Laufzeitbindung von r ist daher nicht wirklich entscheidend.
Es ist doch das selbe Objekt. r und this haben die selbe Adresse, zeigen auf den selben Speicherbereich, also sind es die selben Objekte. Es wird ja kein neues Objekt, sondern nur ein Alias für das selbe Objekt erzeugt.
-
groovemaster schrieb:
Genauso wenig wie die Argumente per Referenz zu übergeben. Alexandrescu hat zB mal was dazu geschrieben.
Warte mal. Alexandrescu bezog sich dabei auf eine Kopiersemantik. D.h. (wenn Du das gleiche meinst wie ich, wovon ich aber ausgehe) er hat keineswegs irgendwo geschrieben, dass man Argumente nicht per Referenz übergeben sollte -- außer für den Fall, dass man sie danach eh kopiert. Folgender Code ist natürlich ein wenig unsinnig:
void foo(T const& v) { T tmp = v; // Kopie // ... }Dann hätte man nämlich gleich eine Kopie übergeben können. Aber ansonsten sollte man bei non-PODs durchaus immer Referenzen verwenden.
-
@Konrad
Ja, das meinte ich. Aber mir ist nicht ganz klar, worauf du hinaus willst. Dein Beitrag steht doch in keinem Widerspruch zu meiner Aussage. Richtlinien sind nunmal nicht zwingend oder implizieren Allgemeingültigkeit.DEvent schrieb:
Es ist doch das selbe Objekt. r und this haben die selbe Adresse, zeigen auf den selben Speicherbereich, also sind es die selben Objekte. Es wird ja kein neues Objekt, sondern nur ein Alias für das selbe Objekt erzeugt.
Ich habe ja auch nicht gesagt, dass das, was camper geschrieben hat, falsch ist. Das Beispiel widerstrebt nur dem Design von C++, also dem statischen Typsystem und der daraus resultierenden statischen Fehlerbehandlung. Und auf der Basis, also wo Laufzeitbindung eine Rolle spielt, kann man eben keinen Memberzugriff auf Objektebene spezifizieren. Alles was bleibt, ist der Sichtbarkeitsbereich. Und dort spielt die Laufzeitbindung dann keine Rolle mehr.
-
camper schrieb:
Begründung?
Damit zB sowas nicht möglich ist:
Rational a,b,c; //... a*b = c;Bei einem nicht-Konstanten Rückgabewert würde dies funktionieren...
Aber ich denke mal du weißt das schon und willst mich jetzt eines besseren Belehren
-
Freak_Coder schrieb:
camper schrieb:
Begründung?
Damit zB sowas nicht möglich ist:
Rational a,b,c; //... a*b = c;Bei einem nicht-Konstanten Rückgabewert würde dies funktionieren...
Aber ich denke mal du weißt das schon und willst mich jetzt eines besseren Belehren

Keineswegs. Ich meine, die Frage, ob man ein derartiges Konstrukt überhaupt verhindern muss, sollte jeder selbst entscheiden. Ich habe selten das Bedürfnis, so etwas zu schreiben.
Wir können Vorkehrungen wegen Murphy treffen, aber gegen Machiavelli ist in C++ sowieso kein Kraut gewachsen.
Immerhin, ein Konstruktion der Arta*b*=can Stelle von
a*b*ckann für eigene Typen durchaus sinnvoll sein, um ein paar unnötige Temporaries loszuwerden, und wir das ganze nicht gerade durch Expressiontemplates lösen.
-
Es geht nicht darum sowas verhindern zu müssen, sondern sicherzustellen das man nicht versehentlich sowas schreibt. Fehler basieren darauf, das man es nciht mit Absicht macht. Wann immer der Compiler in der Lage ist solche Fehler anzumeckern hat man sich selber stundenlandes debuggen erspart.
Jeh genauer man die Bedingungen seiner Funktionen definiert (im Bezug auf public/private ebenso wie const correctness), desto mehr kann einem der Compiler dabei unterstützen Fehler zu verhindern. Für die reine Funktionalität sind die meisten dieser Sachen letzten Endes belanglos. Will sagen, Du kannst ebenso alles public machen und komplett auf const verzichten, laufen wird das Programm dann auch. Nur erhöhst Du damit die Chancen, daß Fehler unbemerkt bleiben... Bis sie dann in Produktion aufschlagen...
-
camper schrieb:
Keineswegs. Ich meine, die Frage, ob man ein derartiges Konstrukt überhaupt verhindern muss, sollte jeder selbst entscheiden.
Ja und wenn ich schon die Möglichkeit habe, solche Fehlerquellen zu ellimnieren, dann versuche ich es auch...
a*b*=cSowas finde ich unschön und das sieht ziemlich ungewoht aus

Ich halt mich nur an das was Meyer in einem seiner Bücher mal geschrieben hat, ungefähr so: "Benutzerdefinierte Typen sollten sich so wie eingebaute verhalten".
Und da dies bei int's und Konsorten auch nicht funktioniert, tue ich dies für meine Typen auch, schue hats eingentlich auf den Punkt gebracht.
Aber jedem seine Entscheidung ...
-
Ich habe ja auch nicht gesagt, dass das, was camper geschrieben hat, falsch ist. Das Beispiel widerstrebt nur dem Design von C++, also dem statischen Typsystem und der daraus resultierenden statischen Fehlerbehandlung. Und auf der Basis, also wo Laufzeitbindung eine Rolle spielt, kann man eben keinen Memberzugriff auf Objektebene spezifizieren. Alles was bleibt, ist der Sichtbarkeitsbereich. Und dort spielt die Laufzeitbindung dann keine Rolle mehr.
Ich versteh dich grade überhaupt nicht.
Camper hat gesagt, wenn man die Sichtbarkeit auf Objektebene regeln könnte, dann kann man erst zur Laufzeit entscheiden ob ein Member sichtbar ist oder nicht. Du hast gesagt das braucht man nicht, da r nicht this ist und somit die Sichtbarkeit zur Compilerzeit entschieden werden kann.
Aber r ist doch this. Ob eine Variable jetzt r oder this heißt ist doch egal, hauptsache sie zeigen beide auf den selben Speicherbereich und sind vom selben Typ.
Also müsstest du fordern das this eine spezielle Variable ist, die einzigartig ist.
int select_foo(const Foo& foo1, const Foo& foo2) { const Foo& r = rand() % 2 ? foo1 : foo2; return r.foo_; }Wie willst du jetzt die Sichtbarkeit entscheiden?
Edit: select_foo ist friend-Funktion der Klasse Foo.
-
DEvent schrieb:
Camper hat gesagt, wenn man die Sichtbarkeit auf Objektebene regeln könnte, dann kann man erst zur Laufzeit entscheiden ob ein Member sichtbar ist oder nicht. Du hast gesagt das braucht man nicht, da r nicht this ist und somit die Sichtbarkeit zur Compilerzeit entschieden werden kann.
Nein, hier bringst du was durcheinander. camper brachte ein Beispiel, was zeigt, wie man Zugriff auf Objektebene unter C++ nicht realisieren kann. Mein Punkt war lediglich der, dass dies unter C++ sowieso nicht zur Debatte steht, weil es nicht zum Konzept von C++ passt. Das einzige was man unter C++ machen kann, ist, den Zugriff auf Objektebene über den Sichtbarkeitsbereich zu regeln, anstatt sich auf Objektidentität zu versteifen.