Nabend allerseits,
ich möchte mal ein Thema zur Diskussion unter den erfahrenen C++'lern stellen, was mir schon seit Anbeginn meiner C++ Zeit Kopfschmerzen bereitet. Eventuell gibt es ja einige C++ Programmierer unter euch, die für das besagte Thema eine Lösung oder gar ein Workaround gefunden haben.
Es geht darum, daß die Sprachspezifikation von C++ gemäß den C Regeln ein "Modul" durch eine deklarierende Headerdatei und eine implementierende Quelldatei definiert. In die Headerdatei kloppen wir unsere Klassendeklaration usw. rein und in die Quelldatei die Methodenimplementierungen usw. Und in dieser Handhabung hat C++ einen bösen "Designfehler" zu verzeichnen...
Das Problem ist nun, daß ich beim Programmieren von Bibliotheken dem "Kunden" die Headerdateien und die vorkompilierte Bibliothek aushändige. Normalerweise laufe ich nicht Gefahr, daß der "Kunde" durch Änderungen an den Headerdateien sich unerlaubte Vorteile oder Zugriffe auf Bereiche der Bibliothek verschaffen kann. Wenn er beispielsweise also die Parameterliste eines Konstruktors ect. ändert und meint, damit irgendwelche Dinge bewirken zu können, die nicht vorgesehen waren, so landet er spätestens beim Kompilieren in der Kloschüssel, weil die Bibliothek bereits vorkompiliert mit entsprechenden Parameterlisten usw. vorliegt.
Allerdings gibt es in C++ ja diverse Möglichkeiten, Klassen so zu designen, daß sie bestimmten Richtlinien unterliegen. So verhindert man die Möglichkeit zur Ableitung von Kindklassen praktischerweise dadurch, indem man sowohl den Standard- als auch den Kopierkonstruktor als "private" deklariert (Java-Coder deklarieren Klassen als "final"). Und hier kommt nun das Problem:
Der "Kunde" kann nun mutwillig die Zugriffsrechte in der Headerdatei von private auf public setzen und so die Klasse wieder ableitbar machen, was nicht vorgesehen war (aus welchen Gründen auch immer). Da die Zugriffsrechte in der Quelldatei gemäß der Syntaxspezifikation von C++ nirgends an- bzw. wiedergegeben werden dürfen, sind sie auch innerhalb der Quelldatei mehr oder weniger "unbekannt". Nur was in der Klassendeklaration steht, hat Auswirkungen auf das Zugriffssystem. Beim erneuten Kompilieren mit der verfälschten Headerdatei meckert der Compiler nicht und der "Kunde" kann die Klasse nun vorsätzlich ableiten, d.h. er hat sie mutwillig ableitbar gemacht.
Leider gibt es nun Klassendesigns in Bibliotheken, die unbedingt solche Ableitungen verhindern MÜSSEN, um die gewünschte Wirkung haben zu können (z.B. Singletons oder reine Factorys). Ein Singleton, welches nachträglich ableitbar gemacht wird, ist per Definition kein Singleton mehr! Da der "Kunde" in Java-Fällen nur die Class- bzw. JAR-Dateien bekommt und nicht die Java-Dateien, ist man dort auf der sicheren Seite. In C++ hingegen kann man solche Definitionen aushebeln...
Also, kann man effektiv in C++ verhindern, daß nachträgliche Änderungen am Zugriffssystem einer Klasse Wirkung haben? Ich denke nein, aufgrund des "schlecht" durchdachten Designs der Sprache. Würde die Syntax erlauben, die Zugriffsqualifizierer auch in den Quelldateien vor jeder Klassenmethode inkl. der Konstruktoren usw. zu schreiben, dann könnte man dieses Problem sofort unterbinden. Jegliche Änderungen am Zugriffssystem seitens der Headerdatei würde einen Konflikt mit den Zugriffen in den Quelldateien beim Kompilieren erzeugen. Wie gesagt, würde...
Für eine anregende Diskussion mit eventuellen Lösungen oder Ansätzen habe ich nun ein sehr offenes Öhrchen
ich möchte mal ein Thema zur Diskussion unter den erfahrenen C++'lern stellen, was mir schon seit Anbeginn meiner C++ Zeit Kopfschmerzen bereitet. Eventuell gibt es ja einige C++ Programmierer unter euch, die für das besagte Thema eine Lösung oder gar ein Workaround gefunden haben.
Es geht darum, daß die Sprachspezifikation von C++ gemäß den C Regeln ein "Modul" durch eine deklarierende Headerdatei und eine implementierende Quelldatei definiert. In die Headerdatei kloppen wir unsere Klassendeklaration usw. rein und in die Quelldatei die Methodenimplementierungen usw. Und in dieser Handhabung hat C++ einen bösen "Designfehler" zu verzeichnen...
Das Problem ist nun, daß ich beim Programmieren von Bibliotheken dem "Kunden" die Headerdateien und die vorkompilierte Bibliothek aushändige. Normalerweise laufe ich nicht Gefahr, daß der "Kunde" durch Änderungen an den Headerdateien sich unerlaubte Vorteile oder Zugriffe auf Bereiche der Bibliothek verschaffen kann. Wenn er beispielsweise also die Parameterliste eines Konstruktors ect. ändert und meint, damit irgendwelche Dinge bewirken zu können, die nicht vorgesehen waren, so landet er spätestens beim Kompilieren in der Kloschüssel, weil die Bibliothek bereits vorkompiliert mit entsprechenden Parameterlisten usw. vorliegt.
Allerdings gibt es in C++ ja diverse Möglichkeiten, Klassen so zu designen, daß sie bestimmten Richtlinien unterliegen. So verhindert man die Möglichkeit zur Ableitung von Kindklassen praktischerweise dadurch, indem man sowohl den Standard- als auch den Kopierkonstruktor als "private" deklariert (Java-Coder deklarieren Klassen als "final"). Und hier kommt nun das Problem:
Der "Kunde" kann nun mutwillig die Zugriffsrechte in der Headerdatei von private auf public setzen und so die Klasse wieder ableitbar machen, was nicht vorgesehen war (aus welchen Gründen auch immer). Da die Zugriffsrechte in der Quelldatei gemäß der Syntaxspezifikation von C++ nirgends an- bzw. wiedergegeben werden dürfen, sind sie auch innerhalb der Quelldatei mehr oder weniger "unbekannt". Nur was in der Klassendeklaration steht, hat Auswirkungen auf das Zugriffssystem. Beim erneuten Kompilieren mit der verfälschten Headerdatei meckert der Compiler nicht und der "Kunde" kann die Klasse nun vorsätzlich ableiten, d.h. er hat sie mutwillig ableitbar gemacht.
Leider gibt es nun Klassendesigns in Bibliotheken, die unbedingt solche Ableitungen verhindern MÜSSEN, um die gewünschte Wirkung haben zu können (z.B. Singletons oder reine Factorys). Ein Singleton, welches nachträglich ableitbar gemacht wird, ist per Definition kein Singleton mehr! Da der "Kunde" in Java-Fällen nur die Class- bzw. JAR-Dateien bekommt und nicht die Java-Dateien, ist man dort auf der sicheren Seite. In C++ hingegen kann man solche Definitionen aushebeln...
Also, kann man effektiv in C++ verhindern, daß nachträgliche Änderungen am Zugriffssystem einer Klasse Wirkung haben? Ich denke nein, aufgrund des "schlecht" durchdachten Designs der Sprache. Würde die Syntax erlauben, die Zugriffsqualifizierer auch in den Quelldateien vor jeder Klassenmethode inkl. der Konstruktoren usw. zu schreiben, dann könnte man dieses Problem sofort unterbinden. Jegliche Änderungen am Zugriffssystem seitens der Headerdatei würde einen Konflikt mit den Zugriffen in den Quelldateien beim Kompilieren erzeugen. Wie gesagt, würde...
Für eine anregende Diskussion mit eventuellen Lösungen oder Ansätzen habe ich nun ein sehr offenes Öhrchen
