Wirkungsbereich von 'friend' eingrenzen oder ganz anderes Konzept
-
Hallo,
danke erst mal für Eure Vorschläge.
Das mit den Interface-Klasse (von Xebov) gefällt mir eigentlich schon recht gut. Allerdings würde ich die Methoden der Interface-Klassen auf public setzen und dafür den Konstruktor auf private und diesem die Basis-Klasse als Freund zuordnen so kann die Interface-Klasse nur von der Basis-Klasse erstellt werden. Die Methoden der Interface-Klasse noch als inline und schon kommt genau der selbe Code raus wie bei meiner Ursprungsidee. Mit diesem Konzept schränke ich zwar nicht den Wirkungsbereich von friend ein dafür ist bei so einer Interface-Klasse die Wahrscheinlichkeit nahe 0 das ich unbeabsichtigte/unerwünschte Methoden der Basis-Klasse aufrufe. So eine Interface-Klasse ist ja nur ein 10-Zeiler und damit auf einen Blick überschaubar und bietet kaum Fehlerpotential.
Die andere Idee (vom pumuckl) hat auch was für sich und ist wohl dichter an der OOP-Philosophie. Aber ich empfinde das virtual als Nachteil (zusätzlicher Code) außerdem müssen auf manche der speziellen Basis-Methoden mehrere Worker-Klassen zugreifen so das da Mehrfach-Erbung möglicherweise zum Problem wird.
Ich werde da auf jeden Fall noch mal ne Nacht drüber schlafen.
Danke für Eure Ideen!
gutes Nächtle
Erik
-
Ich löse das immer indem ich solche Funktionen public mache und denen einen zusätzlichen parameter const char password* mitgebe und somit nur Leute die das Passwort kennen diese Methoden nutzen können.
-
C++-Profi schrieb:
Ich löse das immer indem ich solche Funktionen public mache und denen einen zusätzlichen parameter const char password* mitgebe und somit nur Leute die das Passwort kennen diese Methoden nutzen können.
manchma sind trolls ja fast lustig... xD
-
Erik.Vikinger schrieb:
Das mit den Interface-Klasse (von Xebov) gefällt mir eigentlich schon recht gut. Allerdings würde ich die Methoden der Interface-Klassen auf public setzen und dafür den Konstruktor auf private und diesem die Basis-Klasse als Freund zuordnen so kann die Interface-Klasse nur von der Basis-Klasse erstellt werden.
Der Sinn des privates ind er Interface Klasse war von mir allerdings so erdacht das außer den Workern keienr Zugriff hat, damit wären die Funktionen durchweg abgeschirmt.
unskilled schrieb:
manchma sind trolls ja fast lustig... xD
Ja du mußt aber zugeben die Idee hat was

-
Hallo,
Xebov schrieb:
Der Sinn des privates ind er Interface Klasse war von mir allerdings so erdacht das außer den Workern keienr Zugriff hat, damit wären die Funktionen durchweg abgeschirmt.
Jepp, verstanden. Ich denke ich werde den Constructor private machen und mit der Basis-Klasse befreunden und die eigentlichen Arbeitsmethoden (und den Copy-Constructor) als protected mit der Worker-Klasse als Freund.
Sicher nicht die reine OOP-Lehre, aber für mein derzeitiges Problem ganz brauchbar.
Wie kann ich eigentlich verhindern das von diesen Klassen abgeleitet wird?
Xebov schrieb:
Ja du mußt aber zugeben die Idee hat was

Sowas ähnliches hab ich mal in Assembler gemacht. Da hab ich dem Aufrufer bei Funktion A ein Random-Secret zusammen mit seinen Daten mitgegeben damit sich eben dieser Aufrufer bei Funktion B wieder ordentlich identifizieren konnte. Es ist in der eigentlichen Anwendungslogik leider vorgekommen das die Datenpakete durcheinander kamen. Mit der Sicherheitsabfrage konnten wir aber schnell den Fehler finden. In heutigem C++ möchte ich aber schon das sowas der Compiler macht und nicht ich mit Code zur Laufzeit.
Grüße und Danke für Eure Vorschläge!
Erik
-
Erik.Vikinger schrieb:
Jepp, verstanden. Ich denke ich werde den Constructor private machen und mit der Basis-Klasse befreunden und die eigentlichen Arbeitsmethoden (und den Copy-Constructor) als protected mit der Worker-Klasse als Freund.
Den Copykonstruktor und die Arbeitsmethoden würde ich auch Privat machen, du kannst die Interfaceklasse als Singleton nehmen du brauchst sie ansich ja eh nur einmal.
Erik.Vikinger schrieb:
Wie kann ich eigentlich verhindern das von diesen Klassen abgeleitet wird?
Das weiß ich leider nicht, aber wenn du die Arbeitsmethoden privat hast ziehen ohnehin die Vererbungsregeln und die sagen ja das private Sachen zwar vererbt werden, die erbende Klasse aber keinen direkten Zugriff hat (deswegen gibt es ja protected). Und damit wäre eine Vererbung eh Sinnlos.
-
Hallo Xebov,
Xebov schrieb:
Den Copykonstruktor und die Arbeitsmethoden würde ich auch Privat machen,
Dann hätte aber die Worker-Klasse Zugriff auf den privaten Pointer auf die Basis-Klasse.
Xebov schrieb:
du kannst die Interfaceklasse als Singleton nehmen du brauchst sie ansich ja eh nur einmal.
Ich möchte eigentlich jeder Worker-Klasse eine Kopie geben:
class Interface { private: BaseClass* const base; protected: inline int baseMethode(...) const { return(base->baseMethode(...)); } }; class Worker { private: const Interface iface; public: void func1() { ...; int = iface.baseMethode(...); ...; } };Durch das 'inline', in der Interface-Klasse, macht der Compiler exakt den selben Code draus wie wenn die Worker-Klasse direkt die Basis-Klasse aufruft. Da die Interface-Klasse nur den Pointer zur Bais-Klasse enthält ist sie auch nicht größer als ein Pointer. Das heißt diese zusätzliche Sicherheitsebene kostet weder Performance zur Laufzeit (auch wenn das bei dieser Aufgabe kein Kriterium ist) noch zusätzlichen Speicher (was eventuell dann doch relevant sein könnte).
Wenn die Interface-Klasse ein extra Singletone ist und die Worker-Klassen nur einen Pointer bekommen so muss pro Aufruf eine zusätzliche Dereferenzierung durchgeführt werden, also mindestens ein zusätzlicher Speicherzugriff. Okay, das bisschen extra Speicher für die eine Singletone-Interface-Klassen-Instanz pro Worker-Klasse (es gibt verschiedene Worker-Klassen) ist auch verschmerzbar aber IMHO einfach nicht nötig.Xebov schrieb:
... aber wenn du die Arbeitsmethoden privat hast ziehen ohnehin die Vererbungsregeln ...
Das wirkt aber auch beim Constructor. Der einzigste richtige Constructor in der Interface-Klasse ist private und damit selbst von einer abgeleiteten Klasse aus nicht zu erreichen. Und ohne diesen privaten Constructor kann auch nicht der private Pointer zur Basis-Klasse initialisiert werden und ohne den laufen die protected Interface-Methoden ins leere/Nirvana. Da die erbende Klasse kein super(..) machen kann dürfte der Compiler das erben sowieso zuverlässig verhindern.
Am liebsten währe es mir aber wenn man für jedes Element in einer Klasse haarklein definieren könnte wer alles wie zugreifen darf. Aber wir leben eben nicht in einer perfekten Welt und das ist auch gut so sonst hätten wir jetzt nichts zu diskutieren.
Danke noch mal für Deine Mühe!
Grüße
Erik
-
Erik.Vikinger schrieb:
Dann hätte aber die Worker-Klasse Zugriff auf den privaten Pointer auf die Basis-Klasse.
Das wäre total egal, wenn die Basisklasse die Methdoen privat hat, dann kann der Worker eh nicht drauf zugreifen obe r den Pointer hat oder nicht, er kann damit nichts anstellen.
Erik.Vikinger schrieb:
Durch das 'inline', in der Interface-Klasse, macht der Compiler exakt den selben Code draus wie wenn die Worker-Klasse direkt die Basis-Klasse aufruft. Da die Interface-Klasse nur den Pointer zur Bais-Klasse enthält ist sie auch nicht größer als ein Pointer. Das heißt diese zusätzliche Sicherheitsebene kostet weder Performance zur Laufzeit (auch wenn das bei dieser Aufgabe kein Kriterium ist) noch zusätzlichen Speicher (was eventuell dann doch relevant sein könnte).
Wenn die Interface-Klasse ein extra Singletone ist und die Worker-Klassen nur einen Pointer bekommen so muss pro Aufruf eine zusätzliche Dereferenzierung durchgeführt werden, also mindestens ein zusätzlicher Speicherzugriff. Okay, das bisschen extra Speicher für die eine Singletone-Interface-Klassen-Instanz pro Worker-Klasse (es gibt verschiedene Worker-Klassen) ist auch verschmerzbar aber IMHO einfach nicht nötig.Zum Thema Inline empfehle ich einen Blick in diesen thread http://www.c-plusplus.net/forum/viewtopic-var-t-is-236407.html
Erik.Vikinger schrieb:
Am liebsten währe es mir aber wenn man für jedes Element in einer Klasse haarklein definieren könnte wer alles wie zugreifen darf. Aber wir leben eben nicht in einer perfekten Welt und das ist auch gut so sonst hätten wir jetzt nichts zu diskutieren.
Das willst du nicht glaub mir, da würdest du nie fertig werden mit den Listen der Zugriffsrechte.
-
Hallo,
Xebov schrieb:
Zum Thema Inline empfehle ich einen Blick in diesen thread ...
Das 'inline' nicht bindend ist wusste ich bereits, trotzdem Danke.
Es reicht aber um dafür zu sorgen das mein Code von vorhin und
class Worker { private: const Base_Class base; public: void func1() { ...; int = base->baseMethode(...); ...; } };exakt den selben Code erzeugen, beim gcc sogar ohne besondere Optimierungsparameter. Ich bekomme also zusätzliche Sicherheit ohne irgendwelche Nachteile an Performance/Speicherverbrauch. Die Weiterleitungsfuktion selber besteht im Endeffekt nur aus dem Call-Befehl und sonst nichts (natürlich kommt noch ein Return-Befehl) und weniger währe der Aufruf einer externen Weiterleitungsfuktion auf jeden Fall auch nicht.
Xebov schrieb:
Das willst du nicht glaub mir, da würdest du nie fertig werden mit den Listen der Zugriffsrechte.
Wieso nicht?
Es währe schon schön wenn man definieren könnte ob private Instance-Privat heißt oder nur Klassen-Privat. Public als anderes extrem ist auch eindeutig. Das einzigste was Arbeit macht ist wenn man Zugriffe nur für bestimmte (abgeleitete) Klassen erlauben will und das ist nun so häufig auch nicht. Das 'package' von Java, als Vereinfachung für den Mittel-Fall zwischen public und privat, währe noch ganz hübsch.Grüße
Erik
-
Erik.Vikinger schrieb:
Wieso nicht?
Naja stell dir vor du hast private und protected und müsstest für jedend er da was brauch jedesmal extra ausnahmen deffinieren, bei ner Bibliothek könnte das durchaus ärger geben. Und so eine Durchleitung ist nicht so aufwendig das man da Probleme bekommt.