c++ private member zugriff - Trick erklärung gesucht

OP #4489496
Lesenswert?
• ▲
▼
Hi,
ich würde mich jetzt nicht gerade unerfahren in C++ nennen, aber
das kapier ich überhaupt nicht:

http://bloglitb.blogspot.de/2011/12/access-to-private-members-safer.html

Kann mir jemand erklären, was da passiert? Bzw, warum das funktioniert 
(weil das tut es ohne compiler warnung)?

Weder der Code noch die Erklärung bringt mich weiter.
Was ist ein "Tag"? ich kenn den Begriff nur von den C-Strukturnamen.

wie funktioniert das mit dem Templateparameter M, der ja zurückgegeben 
wird. Sieht hier aus, wie eine Textersetzung, aber c++ templates sind 
dies ja explizit nicht.
Wie funktioniert das friend im Rob? wozu die inline Friend deklarationen 
mit definition?
oder firend definition im A_f.

Oder warum funktioniert der Aufruf a.*get ?

Ich fühl mich gerade, als hätte ich noch nie C++ geschrieben O_o
#4489566
Lesenswert?
• ▲
▼
Der eigentliche Trick an dem Ganzen scheint wohl zu sein, dass bei einer 
expliziten Instanzierung die üblichen Zugriffsregeln nicht gelten (siehe 
letzter Kommentar auf der Seite). Also gibt es bei der Zeile
1
template struct Rob<A_f, &A::a>;
keinen Fehler, obwohl A::a private ist. Der restliche Code dreht sich 
wohl darum, dass die get Funktion per ADL (Argument Dependent Lookup) 
gefunden wird und die gewünschte Adresse auf die private Variable zurück 
liefert.

Um die richtige Funktion zu finden wird hier quasi Tag Dispatch genutzt. 
Wenn man das Beispiel mit mehreren Klassen und Variablen machen möchte 
muss man die get Funktionen irgendwie unterscheiden. Das passiert durch 
durch den einzigen Parameter dieser Funktion.

Edit: So sähe es ohne Tags aus:
1
#include <iostream>
2

3
template <class T, T ptr>
4
struct Rob
5
{
6
  friend T get() {
7
    return ptr;
8
  }
9
};
10

11
// use
12
struct A {
13
  A(int a):a(a) { }
14
private:
15
  int a;
16
};
17

18
template struct Rob<int A::*, &A::a>;
19
int A::* get();
20

21
int main() {
22
  A a(42);
23
  std::cout << "proof: " << a.*get() << std::endl;
24
}
OP #4489633
Lesenswert?
• ▲
▼
ccc schrieb:
> Was macht denn das
> int A::*

"int A::* "  heißt, es handelt sich um einen Member-Pointer auf ein int.

"get()" liefert genau einen solchen Pointer zurück. dieser muss 
dereferenziert werden mittels "a.*get()"  da es ein Memberpointer ist, 
kann dieser nur mit einer Instanz dereferenziert werden, das passiert 
durch das a.*<memberpointer>.
#4489655
Lesenswert?
• ▲
▼
Vlad T. schrieb:
> warum ist die Zeile "int A::* get();" nötig?
> ich dachte, das wird durch die Rob-friend definition erledigt -->
> http://en.cppreference.com/w/cpp/language/friend (2)

Irgendwelche wirren Regeln. Es gibt zwar eine Definition für die 
Funktion aber irgendwie keine globale Deklaration. Durch ADL kann man 
die Funktion auch finden aber wohl nicht einfach so wenn man keine extra 
Deklaration hinzufügt.
OP #4489658
Lesenswert?
• ▲
▼
Sebastian V. schrieb:
> Irgendwelche wirren Regeln. Es gibt zwar eine Definition für die
> Funktion aber irgendwie keine globale Deklaration. Durch ADL kann man
> die Funktion auch finden aber wohl nicht einfach so wenn man keine extra
> Deklaration hinzufügt.

Kurios und eigentlich ein Wunder, das die Compilerhersteller da durch 
sehen und vor allem Compiler erzeugen die unterienander weitestgehend 
das selbe machen ^^.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.