abstrakte Klasse und error: 'void Etwas::test()' is inaccessible
-
Hallo NG,
ich hab eine kurze Frage. Zuerst der Sourcecode
irgendetwas.h
class Irgendetwas { public: virtual void machmal() const = 0; void test(); };irgendetwas.cpp
#include "irgendetwas.h" void Irgendetwas::test() { // Irgendeine implementierung }etwas.h
#include "irgendetwas.h" class Etwas : protected Irgendetwas { // Warum führt protected zu einer // Fehlermeldung beim compilieren public: Etwas(); virtual ~Etwas(); void machmal() const; };main.cpp
#include <iostream> #include <cstdlib> #include "etwas.h" using namespace std; int main(int argc, char *argv[]) { Etwas *e1 = new Etwas(); e1->machmal(); e1->test(); // error: 'void Etwas::test()' is inaccessible delete e1; return EXIT_SUCCESS; }Soweit ich weiß heißt protected, dass eine abgeleitete Klasse auf Methoden zugreifen kann. Warum läßst sich der Sourcecode nicht compilieren? Schreibe ich statt "protected" "public" geht es.
Gruß,
BlackPepper
-
Bei einer protected-Vererbung rutschen die public-Member in den protected Bereich der abgeleiteten Klasse. main() hat mit der Ableitung nix am Hut, ergo kann er auf den protected-Bereich nicht zugreifen. Und Etwas::test() ist durch die protected-Vererbung nur noch protected.
-
l'abra d'or schrieb:
Bei einer protected-Vererbung rutschen die public-Member in den protected Bereich der abgeleiteten Klasse. main() hat mit der Ableitung nix am Hut, ergo kann er auf den protected-Bereich nicht zugreifen. Und Etwas::test() ist durch die protected-Vererbung nur noch protected.
Irgendwie mußt Du mir das genauer erklären. Eine abgeleitete Klasse sollte doch auf "protected Member" zugreifen können, oder? Etwas hat "protected" geerbt, nicht main. Und Etwas greift auf test() zu, nicht main. Oder sehe ich da etwas falsch? Müßte es in Etwas eine funktion test() geben, die test() in "Irgendetwas" aufruft? Und wenn ja, warum? Warum kann ich nicht Etwas instanziieren und auf test() in Irgendetwas zugreifen?
Gruß,
BlackPepper
-
BlackPepper schrieb:
Und Etwas greift auf test() zu, nicht main. Oder sehe ich da etwas falsch?
Genau das ist der Teil, den du falsch siehst. Natürlich greift main hier auf test zu. Der Aufruf von test steht in main.
Wie sonst würde es deiner Meinung nach aussehen, wenn main auf test zugreift?
-
BlackPepper schrieb:
Und Etwas greift auf test() zu, nicht main. Oder sehe ich da etwas falsch?
Jo
int main() { // .. e1->test(); // error: 'void Etwas::test()' is inaccessible // .. }
-
Du kannst aber nur public Elementfunktionen von außen aufrufen! Eine protected Ableitung macht doch nur Sinn, wenn man die abgeleitete Klasse nur intern benötigt.
-
Du darfst den Zugriff nicht aus Instanz-Sicht sehen. Die übliche Sicht von Methodenaufrufen als "Nachricht senden" hilft hier vllt. etwas. "public" heißt: jeder und alles darf mir Nachrichten senden. protected heißt "nur Instanzen meiner Klasse und meine Kinder dürfen mir Nachrichten senden, oder meine friends". Und "main" ist keines von dem.
Du kannst aber so etwas "erzwingen":
main als friend von Etwas deklarieren
im Public-Bereich von Etwas ein "using Irgendetwas::test;"
public erben
Aber erzwinge nie etwas, was sich mit besserem Design umgehen lässt. Soll heißen: erbe public - hier scheint mir das die gewollte Herangehensweise.
-
MFK schrieb:
BlackPepper schrieb:
Und Etwas greift auf test() zu, nicht main. Oder sehe ich da etwas falsch?
Genau das ist der Teil, den du falsch siehst. Natürlich greift main hier auf etwas zu.
Wie sonst würde es deiner Meinung nach aussehen, wenn main auf etwas zugreift?
Nach mir instanziiert main Etwas und benutzt die Methoden in Etwas. Wenn Etwas von Irgendetwas geerbt hat, hat Etwas auch die "protected" Methoden von Irgendetwas geerbt und deshalb hätte ich erwartet daß folgender Code in main funktioniert.
Etwas *e1 = new Etwas(); e1->test(); delete e1;Nach meinem Verständnis hätte man mit eine Klasse
class Speziell : public Etwas { };nicht mehr auf test(); zugreifen können. Also
Speziell *s1 = new Speziell(); s1->test(); // hätte nicht mehr funktioniert delete s1;geht nicht mehr.
Gruß,
BlackPepper
-
Ich denke, du solltest die Kapitel über Vererbung und Elementzugriff/Zugriffs-Spezifizierer nochmal lesen. Das sollte in deinem Buch (welches hast du) eigentlich ganz gut beschrieben sein.
-
protectedheisst doch simpel beschrieben, dass nur die Klasse selbst und abgeleitete auf den Member zugreifen können.mainist aber weder die Klasse selbst, noch davon abgeleitet. Ergo: Der Zugriff ist nicht erlaubt.
-
l'abra d'or schrieb:
Ich denke, du solltest die Kapitel über Vererbung und Elementzugriff/Zugriffs-Spezifizierer nochmal lesen. Das sollte in deinem Buch (welches hast du) eigentlich ganz gut beschrieben sein.
Das werd ich auf alle Fälle. Ich dieses http://www.buecher.de/shop/lehr-und-handbuecher/c/breymann-ulrich/products_products/detail/prod_id/22488637/ Buch in einer älteren Ausgabe. Jedenfalls Danke soweit.
Gruß,
BlackPepper