Member abstrakter basisklasse in abgeleiteter zugänglich machen
-
template<class T> class Bear : public Affe<T> { public: Bear<T>(int var_) : Affe<T>(var_) {} void foo() { std::cout << Affe<T>::var1 << std::endl; Affe<T>::var1 = 3; std::cout << Affe<T>::var1 << std::endl; std::cout << Affe<T>::var2 << std::endl; }; };
-
danke dir aber muss ich dann wirklich IMMER den klassennamen angeben? geht das nicht anders auch?
-
template<typename T> class Bear : public Affe<T> { using Affe<T>::var2; // <-- public: void foo() { var2 = 2; } };
-
ok vielen dank. jetzt würde mir aber glaube ich eine erklärung gut tun...warum gibt es da einen unterschied und warum geht das nur so? tut mir leid für die dumme frage...aber ich verstehe nicht warum es bei templates einen unterschied macht.
danke für weitere erklärungen
-
Du kennst es so, wenn eine Klasse eine andere Klasse erweitert, dann kannst du Member der Basisklasse zugreifen, weil die Erweiterung in gleichen Gültikeitsbereich stattfindet. Die Instanzierung eines Typens hat ihren eigenen Gültigkeitsbereich. Wenn du aber eine Klassentemplate schreibst, bist du selbst in keine Instanz eines Typen drin, daher muss diese Information expliziet angeben.
-
Kurze Antwort: Steht so im Standard.
Ich nehme an, der Grund sind Spezialisierungen und ungewollte und -übersichtliche Nebeneffekte. Nimm etwa
typedef double value_t; template<typename T> struct A {}; template<typename T> struct B : public A<T> { value_t x; }; template<> struct A<int> { typedef int value_t; }; // ... B<int> b; // b.x bleibt double.Der Compiler geht davon aus, dass der Autor von B sich darauf verlässt, dass value_t die im globalen Namensraum definierten Eigenschaften besitzt. Wenn eine Überdeckung durch bestimmte Eigenschaften von A gewünscht ist, kann es halt per using-Direktive erklärt werden.
-
-.-
-
@seldon
Ich meine gelesen zu haben, dass man class anstatt typename vorziehen sollte wenn man weiß, das eine Klasse übergeben wird.
-
Kóyaánasqatsi schrieb:
@seldon
Ich meine gelesen zu haben, dass man class anstatt typename vorziehen sollte wenn man weiß, das eine Klasse übergeben wird.Spielt überhaupt keine Rolle. Sind völlig äquivalent.
-
Nahezu äquivalent. Man kann etwa
template<template<typename> class TT> struct A { };nicht als
template<template<typename> typename TT> // Fehler! struct A { };schreiben. Ansonsten ist es Geschmackssache, welches Schlüsselwort man benutzt - ich bevorzuge typename, weil es mir klarer erscheint (die Vorlage wird ja durch die Benutzung von "class" nicht auf Klassen beschränkt), aber man könnte mit hinreichend mathematischer Anschauungsweise den Standpunkt vertreten, dass Basistypen auch Klassen (von Objekten) sind.
class zu schreiben, um zu signalisieren, dass man eine Klasse erwartet, scheint mir aber nicht sonderlich sinnvoll - man erwartet ja in so einem Fall nicht irgendeine Klasse, sondern eine Klasse, die bestimmte Anforderungen, die die Vorlage benötigt, erfüllt. Das muss man dann eh sinnvoll dokumentieren.