Es gibt keine Funktion, die Sichtbarkeit / Zugänglichkeit der Klasse in C ++ kontrolliert .
Gibt es eine Möglichkeit, es zu fälschen?
Gibt es irgendein Makro / Template / Magie von C ++, das das nächste Verhalten simulieren kann?
Util.h (Bibliothek)
%Vor%B.h (Bibliothek)
%Vor%C.h (Bibliothek)
%Vor%D.h (Benutzer)
%Vor% Erzeuge alle Mitglieder von Util
als privat und deklariere dann: -
( Bearbeiten: Vielen Dank A.S.H für "keine Vorwärtsdeklaration erforderlich".)
Nachteil: -
Util
, um B
und C
irgendwie zu erkennen. Util
zugreifen, brechen Sie% access_guard% access_guard ab
Es gibt eine Möglichkeit, einen Freund nur für einige Mitglieder zu aktivieren Aber es ist nicht so süß und für diesen Fall unbrauchbar. private
kann D
nicht verwenden, aber kann sie trotzdem sehen. Util
ist immer noch eine Option, wenn Sie die automatische Vervollständigung verwenden (zB Strg + Leerzeichen ) in Util
. (Bearbeiten) Hinweis: Es dreht sich alles um Komfort beim Codieren; um einen Bug oder eine schlechte Verwendung zu verhindern / bessere Autovervollständigung / bessere Kapselung. Hier geht es nicht um Anti-Hacking oder um unbefugten Zugriff auf die Funktion zu verhindern.
(Bearbeiten, akzeptiert):
Leider kann ich nur eine Lösung akzeptieren, also habe ich
Für zukünftige Leser: Preet Kukreti (& amp; texasbruce im Kommentar) und Shmuel H (& amp; ASH ) stark> ist Kommentar) hat auch gute Lösungen zur Verfügung gestellt, die es wert sind, gelesen zu werden.
Eine mögliche Lösung wäre, Util
in einen Namespace und typedef
it in die Klassen B
und C
zu schieben:
Wenn die Klasse Util
in util.cpp
implementiert ist, würde dies ein Wrapping in namespace util_namespace { ... }
erfordern. Soweit B
und C
betroffen sind, kann sich ihre Implementierung auf eine Klasse mit dem Namen Util
beziehen, und niemand würde dies wissen. Ohne die Aktivierung von typedef
findet D
keine Klasse mit diesem Namen.
Ich denke, dass der beste Weg ist, Util.h
überhaupt nicht in einen öffentlichen Header aufzunehmen.
Um dies zu tun, #include "Util.h"
nur in der Implementierung cpp
file:
Lib.cpp
:
Dadurch stellen Sie sicher, dass die Änderung von Util.h
nur in Ihren Bibliotheksdateien und nicht in den Benutzern der Bibliothek einen Unterschied macht.
Das Problem bei diesem Ansatz ist, dass Util
nicht in Ihren öffentlichen Headern ( A.h
, B.h
) verwendet werden kann. Vorwärts-Deklaration könnte eine Teillösung für dieses Problem sein:
Eine Möglichkeit besteht darin, eine einzige Zwischenklasse anzusprechen, deren einziger Zweck es ist, eine Zugriffsschnittstelle für die zugrunde liegende Funktionalität bereitzustellen. Dies erfordert ein wenig Standard. Dann sind A
und B
Unterklassen und können daher die Zugriffsschnittstelle verwenden, aber nicht direkt in Utils
:
Weder A
noch B
haben direkten Zugriff auf Util
. Client-Code kann UtilAccess
-Member auch nicht über A
oder B
-Instanzen aufrufen. Das Hinzufügen einer zusätzlichen Klasse C
, die die aktuelle Util
-Funktionalität verwendet, erfordert keine Änderung am Code Util
oder UtilAccess
.
Dies bedeutet, dass Sie eine bessere Kontrolle über Util
haben (insbesondere wenn es zustandsbehaftet ist), um den Code leichter zu verstehen, da der Zugriff über eine vorgeschriebene Schnittstelle erfolgt, anstatt direkten / versehentlichen Zugriff auf anonymen Code zu gewähren A
und B
).
Dies erfordert einen Textbaustein und propagiert nicht automatisch Änderungen von Util
, jedoch ist es ein sichereres Muster als direkte Freundschaft.
Wenn Sie keine Unterklasse erstellen möchten und Sie UtilAccess
für jede verwendende Klasse ändern möchten, können Sie die folgenden Änderungen vornehmen:
Es gibt auch einige verwandte Lösungen (für eine strengere Zugriffskontrolle auf Teile einer Klasse), eine namens Attorney-Client und die andere PassKey , auf die beide eingegangen sind diese Antwort: saubere C ++ granulare Freund gleichwertig? (Antwort: Attorney-Client Idiom) . Rückblickend denke ich, dass die Lösung, die ich vorgestellt habe, eine Variante des Attorney-Client-Idioms ist.
Tags und Links c++ visual-studio-2015 class-visibility