Deklarieren Sie eine member-Funktion, eine vorwärts-deklarierte Klasse als Freund
Ist es möglich zu erklären, eine member-Funktion der vorwärts-deklarierte Klasse als Freund? Ich versuche, Folgendes zu tun:
class BigComplicatedClass;
class Storage {
int data_;
public:
int data() { return data_; }
//OK, but provides too broad access:
friend class BigComplicatedClass;
//ERROR "invalid use of incomplete type":
friend void BigComplicatedClass::ModifyStorage();
};
So ist das Ziel, (i) die Einschränkung der friend-Deklaration auf eine einzige Methode, und (ii) nicht um die definition, die komplizierte Klasse zu reduzieren compile-Zeit.
Ein Ansatz sein könnte, um eine Klasse handeln als Vermittler:
//In Storage.h:
class BigComplicatedClass_Helper;
class Storage {
//(...)
friend class BigComplicatedClass_Helper;
};
//In BigComplicatedClass.h:
class BigComplicatedClass_Helper {
static int &AccessData(Storage &storage) { return storage.data_; }
friend void BigComplicatedClass::ModifyStorage();
};
Jedoch, dies scheint ein bisschen ungeschickt... also gehe ich davon aus, dass es eine bessere Lösung!
- möglich, Duplikat der Wie erklären Sie einem Freund, der ein Mitglied die Funktion eines anderen noch nicht definierte Klasse in C++?
- Danke für den Verweis-ich sah diese Frage, aber die akzeptierte Antwort ist die zu-breiten-Klasse-level-Zugriff, die ich vermeiden wollte...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als @Ben sagt, es ist nicht möglich, aber Sie können bestimmte Zugriff nur auf, dass die Funktion über einen "passkey". Es funktioniert ein bisschen wie die intermediate-helper-Klasse, aber ist imho klarer:
StorageDataKey *key_ptr = 0; StorageDataKey key(*key_ptr);
damit den copy-Konstruktor private zu machen scheint viel Sinn.data
zu einem nicht-ReferenzStorageDataKey
, als müssten Sie die vollständige definition für, die. :/ In C++0x kann man eine rvalue-ReferenzStorageDataKey&&
, obwohl ich denke, dass kann umgangen werden, auch mit einem einfachenstd::move
... Hm.storage_.data(*key_ptr)
. Ich denkeStorageDataKey
sollteint const id
, die überprüft werden sollten, inStorage
Klasse vor dem Gitter den Zugang.Nein, kann man nicht erklären, die einzelnen member-Funktionen als Freunde, bis Sie habe erklärt worden. Sie können nur mit der gesamten Klasse.
Es möglicherweise oder möglicherweise nicht relevant hier, aber es ist nützlich, uns daran zu erinnern, dass es ist eine wilde Welt jenseits der Reichweite von Klassen und Objekten, in denen Funktionen können frei herumlaufen.
Zum Beispiel, vor kurzem musste ich zum Schluss ein (singleton-Globale statische) system-error-log von einem globalen exception-handler basiert auf einem port von jemand anderem code. Der normale include-Datei für meine Fehler-log-in Konflikt mit der exception-handler-code, denn beide wollten zu include "windows.h" aus Gründen, die ich nicht schauen. Wenn diese und andere Fragen bewogen mich, den konnte ich nicht machen, eine vorwärts-Deklaration von meinem ErrorLog-Klasse Memberfunktionen, was ich Tat, war wrap notwendigen Funktionen in einem globalen scope-Funktion wie diese:
Manche Menschen sind ganz besonders über die Aufrechterhaltung der Integrität Ihrer Klasse Struktur, die Sie unter allen Umständen... und nur selten erkennen, dass die Anwendungen mit diesen Klassen sind unweigerlich auf etwas, das fehlt, die Struktur. Aber es gibt, und verwendet mit bedacht, es seinen Platz hat.
Angesichts des Alters dieser Frage, die ich nicht sah tief in seine Relevanz hier. Alles, was ich wollte zu teilen, war der Meinung, dass manchmal eine einfache umlegemechanismus ist ein sehr cleaner und leichter verstanden alternative zu etwas, das viel mehr Subtilität und cleverness darüber. Subtilität und cleverness dazu neigt, sich geändert zu einem späteren Zeitpunkt von jemand benötigt, um es hinzuzufügen, die nicht vollständig verstehen. Bevor Sie es kennen, Sie haben einen Fehler...