verständnisfrage zu Referenz auf Pointer
-
void fooA(Base*& arg) { ... } void fooB(Base* const& arg) { ... } ... //Derived ist Spezialisierung von Base! Derived* derivedPtr = new Derived; fooA(derivedPtr); //error fooB(derivedPtr); //funztFrage:
Wieso? Liegt es daran, dass Derived* eben nicht vom Typ Base* ist?Ist das ähnlich wie bei:
void fooA(int& a) { ... } void fooB(int const & a) { ... } ... fooA(1); //error, da 1 nicht "änderbar" ist fooB(1); //funztZerbrechen uns hier grad den Kopf darüber
Bitte helft 5 Ingenieuren...
-
Ein X aus Derived hat nichts mit X aus Base zu tun (substituiere X mit "Zeiger auf", "Templateklasse mit Argument" etc.). Zwar kann einem Zeigerwert (also einer Adresse) auf ein Derived-Objekt der Zeigerwert auf das in Derived befindliche Base-Subobjekt zugeordnet werden. Das sagt aber nichts über die Zeigerobjekte des jeweiligen Typs aus.
struct Base { ... }; struct Derived1 : Base { ... }; struct Derived2 : Base { ... }; void foo(Base*& arg) { arg = new Derived2(...); } Derived1* derivedPtr; foo(derivedPtr); // nehmen wir an, das wäre möglich // ups, derivedPtr zeigt plötzlich auf ein Derived2 (eigentlich: das Base-Objekt davon, denn bei der Zuweisung in foo hat eine Konvertierung in Base* stattgefunden)fooB kann dagegen aufgerufen werden, hier wird ein temporäres Objekt des Typs Base* erzeugt (mit dem Zeigerwert, der durch die Konvertierung Derived->Base entsteht) und an die Referenz gebunden.
-
Okay. Ich glaub ich hab die Erklärung.
Folgendes ist erlaubt (wenn auch nicht wirklich schön)
void fooA(Base*& arg) { arg = new Base; }Somit würde fooA den Zeiger, der eigentlich ein DerivedPtr war in einen BasePtr ändern udn das darf nicht sein.
ups.. gleichzeitig mit camper geantwortet.
danke, wie immer!
-
wenn du dort Polymorphismus betreiben willst, solltest du es mal so versuchen
void fooA(Base* arg) { ... } ... //Derived ist Spezialisierung von Base! Derived derivedPtr; fooA(derivedPtr);das SOLLTE laufen,bin mir aber nicht 100% sicher.
-
klar, das letzteres funntkioniert. die frage trat auf, weil ein Kollege einen boost::shared_ptr auf eine abgeleitete Klasse per Referenz and eine Methode übergeben wollte, die ausschließlich Referenzen auf shared_ptr der basisklasse verwenden.
Grund war hier, dass er sich den Overhead der Referenzzählung ersparen wollte, wie es bei einem call per value der Fall gewesen wäre
-
Wenn das funktionieren würde, könnte die Variable derivedPtr nach dem Aufruf plötzlich auf eine ganz andere Spezialisierung zeigen.
void fooA(Base*& arg) { arg = new Derived4711; } //... Derived* derivedPtr = new Derived; fooA(derivedPtr); //jetzt wäre derivedPtr urplötzlich ein Zeiger auf Derived4711 //...//EDIT: Mist, viel zu spät
-
Kreppel schrieb:
Wenn das funktionieren würde, könnte die Variable derivedPtr nach dem Aufruf plötzlich auf eine ganz andere Spezialisierung zeigen.
void fooA(Base*& arg) { arg = new Derived4711; } //... Derived* derivedPtr = new Derived; fooA(derivedPtr); //jetzt wäre derivedPtr urplötzlich ein Zeiger auf Derived4711 //...jupp... hab ich ja vor zwei posts geschrieben

-
muffmolch schrieb:
jupp... hab ich ja vor zwei posts geschrieben

Ja, das nächste Mal werde ich auf Refresh oder auf Vorschau drücken, wenn ich beim Schreiben so lange Pause mache...

-
Kreppel schrieb:
muffmolch schrieb:
jupp... hab ich ja vor zwei posts geschrieben

Ja, das nächste Mal werde ich auf Refresh oder auf Vorschau drücken, wenn ich beim Schreiben so lange Pause mache...

das problem kenne ich... kein problem