Friend-access nur für auserwählte protected/private-vars

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Friend-access nur für auserwählte protected/private-vars

Beitrag von kaiserludi »

Folgendes Design schwebt mir vor:

Code: Alles auswählen

public:
  void everyOneShouldBeAbleToCallMe(void);

protected:
  void noOneButFriendsAndSubclassesShouldBeAbleToCallMe(void);

private:
  void noOneButFriendsShouldBeAbleToCallMe(void);

protected:
  void noOneButSubclassesShouldBeAbleToCallMe(void);

private:
  void noOneExceptTheClassItselfShouldBeAbleToCallMe(void);

  friend class IshouldOnlyBeAbleToCallTheTop3ButNotTheBottom2Methods;
  friend void Me::too(void);
Quasi eine Kombination aus C# internal und C++ friend: Access nur für bestimmte Klassen/Methoden (wie friend) nur auf bestimmte Member (wie internal), welche sowohl das unnötige Aushebeln jeglicher Zugriffsbeschränkungen gegenüber dieser Klassen/Methoden durch friend als auch das unnötige Aushebeln jeglicher Zugriffsbeschränkungen aus diese Member druch internal beseitigen und damit eine sauberere Kapselung ermöglichen würde.

Wie implementiere ich das am besten?

Ich habe bereits an so etwas gedacht:

Code: Alles auswählen

class MyClass
{
private:
  friend class IAmAFriend;

  int iAmAccessibleToTheFriend;

  class Privates
  {
     private:
       friend class MyClass;
       int iAmStillPerfectlyPrivateToMyClassAndNotAccessibleByItsFriends;
  } privates;
};
Leider stößt das bei Vererebung schnell an seine Grenzen:

Code: Alles auswählen

class MyClass
{
protected:
  friend class IAmAFriend;

  int iAmAccessibleToTheFriend;

  class Protecteds
  {
     protected:
       friend class MyClass;
       int iAmStillPerfectlyPrivateToMyClassAndNotAccessibleByItsFriends; // still private to MyClass and not accessible to its subclasses, as friendship is not inherited
  } protecteds;
};
Dass Freundschaft nicht vererbt wird, ist ja durchaus korekt und sinnvoll, aber in diesem Fall sorgt es leider dafür, dass ich mit den Freunden auch gleich die Kinder mit ausschließe, weil ich ja nich wissen kann (und auch nicht brauchen sollte), wer einmal von mir erbt und entsprechend in die Liste der Freunde von Protecteds aufgenommen werden müsste, aber meinen Kindern will ich natürlich Zugriff auf meine protecteds, auf die meine Freunde keinen Zugriff haben sollen, geben, sonst könnte ich sie ja gleich zu privates machen...


Gibts es da bereits igendwelche Designpattern, die das umsetzen oder hat wer eine Idee, wie ich das auch für proecteds sauber hin bekomme?
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: Friend-access nur für auserwählte protected/private-vars

Beitrag von BeRsErKeR »

Ich tippe mal, dass es nur mit den Zugriffs-Schlüsselwörtern gar nicht möglich ist. Ein friend hat mindestens genauso viel Zugriff wie eine abgeleitete Klasse. Mit public/protected/private wirst du also nicht wirklich weit kommen. Eine Möglichkeit wäre ein Interface, bei dem man über einen Namen/Identifier bestimmte Werte abfragen oder ändern kann mit entsprechender Prüfung ob der Fragende eine abgeleitete Klasse ist. Allerdings würde das dann wieder einigen Overhead und Programmieraufwand erzeugen.

Die Frage ist, wozu das ganze eigentlich brauchst? Wenn ein friend keinen Zugriff haben soll, aber abgeleitete Klassen, dann bau einfach eine weitere Klasse dazwischen (in der Ableitungshierarchie), die diese Werte enthält und entsprechend weitervererbt. Damit erschlägst du dann schonmal den vorletzten Punkt (allerdings kann die Basisklasse selbst dann nicht mehr darauf zugreifen, sondern nur die Zwischenklasse, oder du machst da wieder ein friend BaseClass rein mit Hilfe von forward declarations). Etwas, auf das nur die Klasse selbst zugreifen kann, hast du ja selbst schon mit der Hilfsklasse im Bauch gefunden. Von daher ist eigentlich alles abgedeckt.
Ohne Input kein Output.
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Friend-access nur für auserwählte protected/private-vars

Beitrag von kaiserludi »

Im vorliegenden Fall möchte ich gerneden Zugriff auf Konstruktoren der Klasse als Protected mit friend-Zugriff haben. Über das öffentliche Interface sollen bestehende Instanzen genutzt und kopiert werden können, ganz neue hingegen sollen nur intern durch eine befreundete Klasse erzeugt werden können. Die braucht aber eigentlich keinen Zugriff auf die Variablen der Klasse, sondern nur auf die nicht öffentlichen Konstruktoren.
Mit eienr weiteren Klasse in der Hierarchie lässt sich das nicht so ohne weiteres lösen, da Konstruktoren ja bekanntlich nicht vererbt werden.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Friend-access nur für auserwählte protected/private-vars

Beitrag von dot »

Was genau willst du denn damit dann machen?
Zuletzt geändert von dot am 13.01.2012, 10:10, insgesamt 1-mal geändert.
Alexander Kornrumpf
Moderator
Beiträge: 2119
Registriert: 25.02.2009, 13:37

Re: Friend-access nur für auserwählte protected/private-vars

Beitrag von Alexander Kornrumpf »

Dein Problem ist doch dass du von der Klasse A deren Instanzen durch B erzeugt werden sollen public erben willst, oder? Vielleicht irre ich mich, aber wenn es einen bestimmten Grund gibt, dass A nur von B erzeugt werden kann, sollte der Grund auch für Kinder von A gelten, sonst wär es kein "ist-ein". Sonst könnte man den kompletten Mechanismus den du da konstruierst ja auch einfach aushebeln, indem man "leer" von A erbt.
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Friend-access nur für auserwählte protected/private-vars

Beitrag von kaiserludi »

dot hat geschrieben:Was genau willst du denn damit dann machen?
Klasse X kommuniziert mit einem Masterserver und lässt sich von diesem regelmäßig Aktualisierungen über die Listen offener Gamerooms und über die Liste der Spieler im Raum, in dem sich der Client aktuell befindet, schicken.
Aus den serialisierten Rohdaten erstellt sie Instanzen der Klassen Room und Actor, welche sie in Vektoren in ihrem öffentlichen Interface bereitstellt.
Nutzer des öffentlichen Interafaces können nun auf diese Instanzen zugreifen und eine Menge readonly-Properties auslesen. Dazu gibts es noch mutable-Subklassen von Room und Actor für den derzeit betretenen Raum und den eigenen Spieler, welche Schreibrechte zur Verfügung stellen.
ein Schreibzugriff auf eine solche Eigenschaft eines Raumes/Spielers löst automatisch eine Nachricht an den Server aus, welcher bei fehlenden Zugriffsrechten einen Fehler schmeißen würde. Um unnötigen Traffic und Inkosistenzen durch eh nicht erlaubten Zugriffe zu vermeiden, schließe ich durch readonly-Zugriff und fehlende Konstruktoren von vorneherein auf Clientseite aus, dass über das öffentliche Interface etwas anderes gemacht werden kann, als voorgesehen, sprich, als lesend auf bereits bestehende Instanzen zuzugreifen.
Alexander Kornrumpf hat geschrieben:Dein Problem ist doch dass du von der Klasse A deren Instanzen durch B erzeugt werden sollen public erben willst, oder? Vielleicht irre ich mich, aber wenn es einen bestimmten Grund gibt, dass A nur von B erzeugt werden kann, sollte der Grund auch für Kinder von A gelten, sonst wär es kein "ist-ein". Sonst könnte man den kompletten Mechanismus den du da konstruierst ja auch einfach aushebeln, indem man "leer" von A erbt.
Der Grund gilt in der Tag auch für Kinder von A.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Alexander Kornrumpf
Moderator
Beiträge: 2119
Registriert: 25.02.2009, 13:37

Re: Friend-access nur für auserwählte protected/private-vars

Beitrag von Alexander Kornrumpf »

Meiner Meinung nach ist die Lösung dann dass nicht jeder einfach von A erben darf. Denn für beliebige Kinder kannst du eben nicht garantieren, dass sie nur via B erzeut werden, oder? Wenn die komplette Klassenhierarchie von A z.B. innerhalb von B steckt und nur ein Interface zurückgegeben wird, wenn B ein A oder ein Kind von A konstruiert brauchst du nichtmal friend. Du verlierst damit halt die Möglichkeit dass außenstehende erben.
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Friend-access nur für auserwählte protected/private-vars

Beitrag von kaiserludi »

Stimmt, daran, dass ich die Konstruktion von erbenden Objekten nicht so einfach unterbinden kann, es sei denn durch private Konstruktoren statt protected, habe ich noch gar nicht gedacht. Wenn ich so drüber nachdenke, macht es aber eigentlich auch wenig Sinn, von diesen Klassen zu erben, womit ich es getrost untersagen könnte.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Friend-access nur für auserwählte protected/private-vars

Beitrag von Krishty »

seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten