5 Stimmen

Typisierung von Zeigern mit und ohne Referenz

Angesichts der Tatsache, dass A* pA; y B* pB; gibt es ANY Unterschied zwischen den nachstehenden Typenbesetzungen (Abfrage für alle Besetzungen im C++-Stil):

pB = reinterpret_cast<B*>(pA);      // pointer
pB = reinterpret_cast<B*&>(pA);     // pointer-reference

5voto

James Kanze Punkte 146902

Die beiden sind radikal verschieden, zumindest in der Theorie (und möglicherweise auf einigen wenigen Maschinen in der Praxis). Die erste nimmt einen Zeiger auf A, und konvertiert ihn in einen Zeiger auf B; zumindest in der Theorie kann dies zu Änderungen in Größe und Darstellung beinhalten. (Ich habe tatsächlich auf Maschinen gearbeitet auf denen char* war größer als int* . Ich bezweifle eher, dass solche Maschinen noch existieren, wenn auch vielleicht in der Embedded-Welt...) Die zweite ist eigentlich das Äquivalent von *reinterpret_cast<B**>(&pA) ; es nimmt die Bits in pA und weist den Compiler an, sie als a B* . Wenn das Format anders ist, haben Sie Pech gehabt, und wenn die Größe anders ist unterschiedlich ist, werden Sie wahrscheinlich nur auf einen Teil der pA oder zum Zugriff auf den Speicher der nicht Teil von pA .

Außerdem ist der erste ein r-Wert, der zweite ein l-Wert. Daher kann etwas wie:

++ reinterpret_cast<B*>( pA );

ist illegal, aber:

++ reinterpret_cast<B*&>( pA );

ist es nicht. Dies ist eine nützliche Technik, um Code zu verschleiern und nicht ausgerichteten Zeigern, Zeigern in der Mitte von Objekten oder anderen Zeigern, die man nicht zu derefenzieren wagt.

Im Allgemeinen sollte die zweite Form vermieden werden, aber es gibt seltene Ausnahmen. Posix garantiert, dass alle Zeiger, einschließlich Zeigern auf Funktionen (aber nicht Zeiger auf Mitglieder - Posix spezifiziert eine C ABI, die keine Zeiger auf Mitglieder kennt), die gleiche Größe und das gleiche Format haben, daher ist die zweite Form garantiert funktionsfähig. Und es ist der einzige Weg, wie Sie legal konvertieren kann. void* zurückgegeben von dlsym in einen Zeiger auf eine Funktion:

int (*pf)( int );
reinterpret_cast<void*&>( pf ) = dlsym( handle, "functionName" );

(In C würden Sie schreiben:

int (*pf)( int );
*(void**)( &pf ) = dlsym( handle, "functionName" );

siehe die offiziell Spezifikation .) Solche Tricks ermöglichen Konvertierungen zwischen Zeigertypen die sonst nicht erlaubt sind, hängen aber von zusätzlichen Garantien ab, die nicht die nicht in der Norm enthalten sind.

1voto

Mihran Hovsepyan Punkte 10420

reinterpret_cast ist implementierungsabhängig. Theoretisch können die Ergebnisse also unterschiedlich sein, aber in der Praxis können Sie davon ausgehen, dass die Ergebnisse gleich sind, weil typeid(B*) ist gleich typeid(B*&) => in beiden Fällen wird derselbe Typ verwendet.

0voto

Alok Save Punkte 196241

Es gibt No Unterschied.

pB = reinterpret_cast<B*>(pA);      // pointer 

auf einen Zeiger des Typs B* et

pB = reinterpret_cast<B*&>(pA);     // pointer-reference

ist das Casting auf eine Referenz auf einen Zeiger.

Hinweis: Es gibt keinen Zeiger auf eine Referenz.

2 Stimmen

In seiner Frage hat OP bereits erwähnt, dass der erste ein Zeiger und der zweite ein Verweis auf einen Zeiger ist.

0 Stimmen

@Mihran Hovsepyan: OP sagte Pointer-Reference so etwas gibt es nicht, oder? Es kann nur einen Verweis auf einen Zeiger geben.

2 Stimmen

Pointer-reference ist auf Englisch dasselbe wie reference of pointer y no pointer to reference .

0voto

Johann Gerell Punkte 24065

No funktionell Unterschied, welcher Art auch immer.

Es gibt offensichtlich einen Unterschied in der Wartbarkeit, wenn Sie die letztere Variante verwenden würden. Ihre Kollegen würden denken, Sie hätten etwas geraucht ;-)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X