String-Klasse erweitern
-
Simon2 schrieb:
b) Warum soll man von Klassen ohne virtuellen Dtor nicht ableiten?
=> War mir anfänglich auch nicht ganz klar, wird es aber, wenn man sich klar macht, wofür der Dtor da ist und wofür man Funktionen virtual macht:
i) Der Dtor soll "hinterher aufräumen"
ii) virtual macht man eine Funktion, wenn eine davon abgeleitete Klasse die Funtionalität anpassen können soll. Wenn also eine Klasse keinen virtuellen Dtor hat, hat eine davon abgeleitete Klasse keine Möglichkeit, das "Aufräumverhalten" anzupassen.Das würde ich anders formulieren: Virtuell macht man eine Funktion, wenn die Funktionalität polymorph verwendet werden soll. Nicht vorhandener virtueller Destruktor ist noch lange kein Grund, um nicht von einer Klasse abzuleiten. Aber es ist ein Grund, die Klasse nicht mit Laufzeitpolymorphie zu verwenden.
Die Unterscheidung halte ich für sehr wichtig, da Vererbung keine Polymorphie impliziert. Das betrifft nicht nur Spezialfälle wie
boost::noncopyableoder Policies.Simon2 schrieb:
Denk dran: Du kannst in der Klasse NICHTS machen, was irgendeine Aufräumaktion hinterher erfordert (und die nicht std::string sowieso macht)
Doch, kann man sehr wohl. Man darf die Instanz nur nicht über einen Basisklassenzeiger zerstören. Dennoch stimme ich dir hier zu und finde, es gibt bessere Lösungen als seine Klasse von
std::stringabzuleiten.Mentras schrieb:
Das wollte ich nicht fragen. Ich will wissen, wieso das Standard-Komitee es für sinnvoll hält ihre Klassen nicht mit einem virtuellen Destruktor zu versehen. Das schränkt doch ein, oder nicht?
Eine virtuelle Funktion und damit eine VTable bei sowas Elementarem wie der Stringklasse wäre wegen des "Zahle nur, was du brauchst"-Prinzips in C++ unvertretbar. Es ist aber auch nicht eine wirklich spürbare Einschränkung.
-
Mentras schrieb:
Simon2 schrieb:
Aber mir fallen spontan 2 Deutungen deiner Frage ein:
a) Warum hat std::string keinen virtuellen Dtor?
=> Eben, weil es nicht als Basisklasse verwendet werden soll.Das wollte ich nicht fragen. Ich will wissen, wieso das Standard-Komitee es für sinnvoll hält ihre Klassen nicht mit einem virtuellen Destruktor zu versehen. Das schränkt doch ein, oder nicht?
Virtuelle Funktionen im Allgemeinen und Destruktoren im Speziellen bringen aber immer Performancenachteile mit sich. Und da man eher selten in die Verlegenheit kommt, Standardklassen abzuleiten, bzw. in einem solchen Falle sehr oft auch mit Wrapperklassen o.ä. zum gewünschten Resultat kommt, entspricht es nicht der C++-Philosophie, diesen Performancenachteil der gesammten C++-Community aufzudrücken.
-
> ist das Beispiel in seinem Buch „Die C++ Programmiersprache?“.
Ich habe es aus "Programming" (Habe ich schon erwähnt, dass das ein wunderbares Buch ist? :)), in TC++PL heißt das Teil "Vec" und findet sich (4.,akt. Auflage
2000) auf Seite 58 (§3.7.2).
-
Du kannst Dir mal die boost string Algorithmen angucken und dich davon inspirieren lassen. Oder Du wirst einfach mit dem, was dir boost da bietet glücklich.
-
@Ad aCTa: Danke

brotbernd schrieb:
Du kannst Dir mal die boost string Algorithmen angucken und dich davon inspirieren lassen. Oder Du wirst einfach mit dem, was dir boost da bietet glücklich.
boost::lexical_cast<T> ist schon Mal ein guter Anfang. Danke!
-
Mentras schrieb:
boost::lexical_cast<T> ist schon Mal ein guter Anfang. Danke!
brotbernd meinte was Anderes.
http://www.boost.org/doc/libs/1_43_0/doc/html/string_algo.html
-
Ich denke, er wollte seiner string-Klasse einfach sowas wie "toInt()", "toDouble()" usw verpassen

-
Simon2 schrieb:
std::string *p = new MyString;ist der code überhaupt valid?

-
Wenn MyString von std::basic_string<> öffentlich geerbt hat, dann ja.
-
Mentras schrieb:
Simon2 schrieb:
Aber mir fallen spontan 2 Deutungen deiner Frage ein:
a) Warum hat std::string keinen virtuellen Dtor?
=> Eben, weil es nicht als Basisklasse verwendet werden soll.Das wollte ich nicht fragen. Ich will wissen, wieso das Standard-Komitee es für sinnvoll hält ihre Klassen nicht mit einem virtuellen Destruktor zu versehen. Das schränkt doch ein, oder nicht?
...Vorab: Ich kenne dich nicht und weiß natürlich nicht, was du weißt und was nicht. Vielleicht hast du viiiieeel mehr Ahnung von C++ (gibt viele).
Die Frage "Welchen Sinn haben nicht-virtuelle Dtoren?" wird hier im Forum fast so oft gestellt wie "Wie trenne ich bei templates die Implementierung?" ... und ich würde die Steller dieser Frage nicht als Dummköpfe hinstellen, sondern eher als "noch nicht allzu Fortgeschirttene" bezeichenen. Und deshalb versuche ich, diese Frage für dieses Zielpublikum zu beantworten (natürlich mit den entsprechenden Verallgemeinerungen).Aber kannst du mirnochmal genau erklären, inwieweit die Frage
"Wieso hält das Standard-Komitee es für sinnvoll, ihre Klassen nicht mit einem virtuellen Destruktor zu versehen?"
nicht mit "Weil man sie nicht als Basisklasse (im Zusammenhang mit Laufzeitpolymorphie) nutzen soll." beantworten kann?Gruß,
Simon2.
-
Simon2 schrieb:
Aber kannst du mirnochmal genau erklären, inwieweit die Frage "Wieso hält das Standard-Komitee es für sinnvoll, ihre Klassen nicht mit einem virtuellen Destruktor zu versehen?"
nicht mit "Weil man sie nicht als Basisklasse (im Zusammenhang mit Laufzeitpolymorphie) nutzen soll." beantworten kann?Er meinte wohl eher:
"Warum will das Standardisierungskomitee nicht, dass manstd::stringnicht als Basisklasse und für Laufzeitpolymorphie benutzt?"Ich kenne die genauen Gründe nicht, aber ich vermute mal, dass das im Sinne der Effizienz und konsistenz war. Alle Container sind nicht für Polymorphie gedacht und bei den meisten anderen macht es auch von der Performance her Sinn. Bei
std::stringwäre es wahrscheinlich nicht so fatal, aber beistd::vectormöchte man den Overhead vielleicht nicht bezahlen müssen.
-
Nicht zu vergessen, daß sich jeder nach Belieben eine eigene String-Klasse mit virtuellem Destruktor schreiben darf.
-
volkard schrieb:
Nicht zu vergessen, daß sich jeder nach Belieben eine eigene String-Klasse mit virtuellem Destruktor schreiben darf.
Und dort könnte man ja auch immernoch
std::stringwrappen und lediglich ein paar Sachen selbst nachliefern.
-
drakon schrieb:
Bei std::string wäre es wahrscheinlich nicht so fatal, aber bei std::vector möchte man den Overhead vielleicht nicht bezahlen müssen.
Eher anders herum. string ist ein Wegwerfprodukt, das möglichst schnell zu löschen sein sollte (bei Stringverkettung mit + und substr werden ständig temporäre Strings erzeugt). Es wäre nicht einzusehen, dass alle den Preis eines virtuellen Destruktors zahlen sollten, obwohl 99.99% ihn nicht brauchen.
Da sich in einem vector meist viele und öfters auch größere Objekte befinden, vermeidet man da Kopien sowieso lieber.