Funktion von Basisklasse wird nicht gefunden
-
Hi, warum wird die Funktion "ToString()" hier nicht gefunden?
class Object { public: Object() {}; }; class Convertible : public virtual Object { public: virtual String* ToString(int i) const = 0; String* ToString() const { return nullptr; }; }; class String { public: String() {}; }; class AClass : public Object, public virtual Convertible { public: AClass(){}; private: virtual String* ToString(int i) const { return new String(); }; }; int main() { AClass a; a.ToString(); return 0; }
-
Weil sie alle ToString heißen versteckt fir eue die alte.
class AClass : public Object, public virtual Convertible { public: AClass(){}; using Convertible::ToString;//mich versteckst du da unten nicht! private: virtual String* ToString(int i) const { return new String(); }; };
-
Ist sowas schönes Design? Hört sich für mich eher erstmal "müllig" an, wenn ein Aufruf an den gleichen Funktionsnamen intern ggf. was anderes tut als von extern.
-
Ganz einfach:
Wenn der Compiler etwas sieht, was er als Funktionsaufruf interpretieren kann, fängt er an die Funktion zu suchen.
Dabei geht er vom Scope, der "am nächsten dran" an der Funktion ist, aus und dann immer weiter in die äußeren. Er hört auf, sobald er eine oder mehrere Funktionen gefunden hat.
In diesem Fall ist das eine Memberfunktion, also fängt er an in der Klassenfunktion des Objektes zu suchen, also von AClass. Dort findet er eine Funktion, also hört er auf.
Es kümmert ihn nicht, dass die Funktion private ist, Zugriffsrechte spielen keine Rolle.
Die Lösung ist entweder die private Funktion umzubennen oder den Aufruf explicit zu qualifizieren.a.Convertible::ToString()Das gängige Idiom in C++ wär in diesem Fall übrigens eine freie Funktion zu schreiben, die via ADL gefunden werden kann.
In Konsistenz zu std::to_string kann man dann in irgend einem generischem Code folgendes schreiben:T a; using std::to_string; // Name bekannt machen return to_string(a); // sowohl std::to_string als auch eine to_string Funktion im Scope von T werden gefunden und die beste ausgewählt
-
@Volkard
Danke das funktioniert. Muss nur leider in jeder abgeleiteten Klasse eingefügt werden.
-
Möchte nur mal drauf hinweisen, dass der Code relativ schrottig ist. So sieht kein gutes C++ aus. So sieht C++ aus, wie es ein Javaprogrammierer schreiben würde.
Beispiel:
String* blah() { String* s = new String("wtf?!"); return s; }-->
std::string blah() { return "besser"; }
-
Natürlich ist das gutes Design! Das sieht man doch schon alleine daran, das jedes Object wirlich auch ein Object ist und als solches behandelt werden kann!