2012-03-28 6 views
1

Ich habe eine statische Bibliothek in C++ geschrieben. Ich habe auch die Header-Dateien für die Klassen in der statischen Bibliothek definiert.Friend-Funktion Zugriff auf die privaten Mitglieder der Klasse in der statischen Bibliothek definiert

Kann ich auf die privaten Mitglieder der Klassen zugreifen, die in der statischen Bibliothek definiert sind und eine Friend-Funktion in die Klassendeklaration einfügen?

+0

der Teufel verwendet: '#define privat public' – smerlin

+0

schön:) ....... aber das wird jede Zeit –

+0

@smerlin nicht: ich vermeiden würde. Aus einer juristischen Sicht ist dies in sich * undefiniertes Verhalten * weil 'private' ein reservierter Bezeichner ist (ein Compiler könnte einen Fehler erzeugen und sich weigern, die Anweisung zu kompilieren oder stillschweigend zu ignorieren). Zweitens hängt das Layout einer Klasse von der Zugriffsebene der Mitglieder ab. Obwohl es sich um ein selten verwendetes Feature handelt, könnten Sie subtile Fehler einführen, indem verschiedene Teile des Programms ein anderes Speicherlayout für das gleiche Objekt erwarten. –

Antwort

1

Sie meinen, Sie möchten die Header ändern, die mit der Bibliothek geliefert werden? Es ist in keiner Weise garantiert, dass das Hinzufügen von friend Deklarationen dort funktioniert. Sie könnte den Linking-Teil durcheinander bringen, auch wenn Ihr Compiler sagt, es ist in Ordnung.

Auch, wenn diese Mitglieder sind private, Sie nur nicht auf sie zugreifen.

+0

Können Sie bitte auf: * Wie * es * könnte * ein Problem sein? –

+0

@Als ich versuchte etwas Ähnliches eine Weile auf Visual Studio zurück. Ich habe den Header selbst bearbeitet und einen privaten mit öffentlichem ersetzt, und ich habe ungelöste Äußerlichkeiten bekommen. * Könnte * kein Problem bei gcc sein, aber ich bin mir ziemlich sicher, dass das Ändern der Kopfzeile nach dem Erstellen der Bibliothek keine gute Idee ist. –

+0

@Luchian: Haben Sie versucht, eine Friend-Funktion in der Klassendeklaration einzuführen und zu sehen, ob Sie auf die privaten Mitglieder zugreifen können? –

1

Es ist technisch undefined Verhalten, eine andere Sequenz von Token zu verwenden, um dieselbe Entität (hier eine Klasse) in verschiedenen Übersetzungseinheiten zu definieren.

Unabhängig von der Technik, die Sie verwenden, solange es die Reihenfolge der Token ändert, die es zusammensetzen, ist es vom Standard her übel (obwohl es in der Praxis wahrscheinlich funktioniert).

Johannes discovered a way dies unter Einhaltung der Norm zu tun. Es basiert auf der Tatsache, dass, obwohl a ist ein privates Attribut in der Klasse A, &A::a kann in Kontexten geschrieben werden, die A.a schreiben können (vielleicht ein Versehen im Standard?).

Core-Methode:

template<typename Tag, typename Tag::type M> 
struct Rob { 
    friend typename Tag::type get(Tag) { 
    return M; 
    } 
}; 

// use 
struct A { 
    A(int a):a(a) { } 
private: 
    int a; 
}; 

// tag used to access A::a 
struct A_f { 
    typedef int A::*type; 
    friend type get(A_f); 
}; 

template struct Rob<A_f, &A::a>; 

int main() { 
    A a(42); 
    std::cout << "proof: " << a.*get(A_f()) << std::endl; 
} 

Erweiterung für Einfachheit:

template<typename Tag, typename Member> 
struct TagBase { 
    typedef Member type; 
    friend type get(Tag); 
}; 

struct A_f : TagBase<A_f, int A::*> { }; 

EDIT:

Dieser Trick ist (witziger) explicitly allowed von der Standard-

§14.7.2/12 Die üblichen Zugriffskontrollregeln gelten nicht für Namen, die explizite Instanziierungen angeben. [...]

+0

Ich kenne den Beitrag, aber '& A :: a' ist immer noch nicht legal. Zumindest glaube ich das nicht. Unter MSVS kompiliert es nicht, und er versäumte es, ein Zitat aus dem Standard zu liefern, als ich ihn fragte, also bin ich über diese Lösung reserviert. http://StackOverflow.com/a/6886432/673730 –

+0

@LuchianGrigore: Ich würde gerne überprüfen, aber ich kann nicht einmal die Referenz finden, die die Syntax '& A :: a' im Standard beschreibt. * pointer to member * ergibt nur ein paar Referenzen ... Kennen Sie den zu verwendenden Begriff oder wo ist die beschriebene Syntax? –

+0

Ich habe keine Ahnung, aber ich bezweifle, dass Sie etwas finden, das sagt, es ist legal. Sie versuchen tatsächlich, die Adresse eines privaten Mitglieds zu erhalten. Sehen Sie nicht, wie oder warum das vom Standard erlaubt wäre. –