Wie neue Memberfunktion zu std::string adden (Wrapperfunktionen, um CString unter linux zu "simulieren")
-
Nexus schrieb:
Tachyon schrieb:
Und was soll das bringen? Dann ist ein
std::stringimmer noch einstd::stringund hat nach wie vor keinGetLength().Ein
std::stringwird immer einstd::stringbleiben und nie einGetLength()haben.Der Wrapper-Vorschlag wurde ja auch schon genannt. Ich hoffe mal nicht, dass es hier an der Aufruf-Syntax scheitert, "weil ja
str.GetLength()so viel objektorientierter ist alsGetLength(str)"...So wie ich das verstanden habe will er erreichen, dass er seinen CString-Client-Code möglichst nicht ändern muss. Das wäre woll nicht zutreffend, wenn man an allen Stellen wo irgendwie mit CString-Objekten rumgemacht wird eine freie Funktion aufrufen müsste. Ein Wrapper wäre wohl sinnvoller. Dann brauchts im Idealfall nur eine Änderung der includes.
-
Ja, der Vorschlag wurde ja wie gesagt schon längst gebracht. Es gibt zwei Anforderungen:
std::stringverwenden- Klasse mit gleichem Interface wie
CString
Dummerweise sind diese nicht vereinbar. Da ChangeMyString mich nach der Umsetzung meiner Variante gefragt hat (wahrscheinlich nicht ganz im Bewusstsein, dass freie Funktionen anders als Memberfunktionen aufgerufen werden), hab ich ihm eben geantwortet.
-
Nexus schrieb:
Ja, der Vorschlag wurde ja wie gesagt schon längst gebracht. Es gibt zwei Anforderungen:
std::stringverwenden- Klasse mit gleichem Interface wie
CString
Dummerweise sind diese nicht vereinbar. Da ChangeMyString mich nach der Umsetzung meiner Variante gefragt hat (wahrscheinlich nicht ganz im Bewusstsein, dass freie Funktionen anders als Memberfunktionen aufgerufen werden), hab ich ihm eben geantwortet.
Es gäbe noch eine dritte Möglichkeit: Alles auf std::string zu portieren. Dann geht es ohne weitere Anpassungen sowohl unter Windows als auch unter Linux.

-
C++? Vererbung!
Ich hab mal sowas gemacht:
#include <string> using namespace std; class sstring : public string { public: explicit sstring(const allocator<char_traits<char> >& al = allocator<char_traits<char> >()) : string(al){}; sstring(const sstring& rhs) : string((string)rhs){}; sstring(const string& rhs) : string(rhs){}; sstring(const sstring& rhs, string::size_type pos, string::size_type n, const allocator<char_traits<char> >& al = allocator<char_traits<char> >()) : string(rhs,pos,n,al){}; sstring(const char *s, string::size_type n, const allocator<char_traits<char> >& al = allocator<char_traits<char> >()) : string(s,n,al){}; sstring(const char *s, const allocator<char_traits<char> >& al = allocator<char_traits<char> >()) : string(s,al){}; sstring(string::size_type n, char c, const allocator<char_traits<char> >& al = allocator<char_traits<char> >()) : string(n,c,al){}; sstring(const_iterator first, const_iterator last, const allocator<char_traits<char> >& al = allocator<char_traits<char> >()) : string(first, last, al){}; size_type GetLength(){return length();}; // ... // Beliebige andere Funktionen z.B. atoi(), makePath() und was das Herz begehrt... // oder eben eine Kopie von CString. // ... };Achtung! Das hier ist hingeschmiert.
Aber so ähnlich würde ich das angehen.Gruß
C.
-
Caligulaminus schrieb:
C++? Vererbung!
Ich hab mal sowas gemacht:
#include <string> using namespace std; class sstring : public string ...Damit wirst du dir ein schönes Speicherleck einfangen weil der Destruktor von std::string nicht virtual ist. Außerdem ist die Verwendung von using namespace std; in Header-Dateien auch nicht grad toll.
-
rean schrieb:
Damit wirst du dir ein schönes Speicherleck einfangen weil der Destruktor von std::string nicht virtual ist.
Ich sehe da kein Speicherleck.
Das von dir beschriebene Problem tritt auf, wenn man Member zu Klassen ohne virtuellen Konstruktor hinzufügt und diese auch noch über einen Basisklassenzeiger löscht. Hier wurden keine Member hinzugefügt.
-
Ich würde
std::stringgleich richtig wrappen. Dieses Gemisch von Namenskonventionen ist grausam. Ausserdem könnte man die über 100 Memberfunktionen vonstd::stringaufs Wesentliche beschränken. Gerade hier scheint mir eine Ableitung vonstd::stringnicht viel zu bringen, da die Basisklasse keine Funktionalität bietet, die genutzt wird (da sie eine komplett andere Schnittstelle alsCStringhat).Generell würde ich nicht von STL-Containern erben, da diese nicht dazu designed sind. Im Normalfall – wenn es nicht nur darum geht, Code einer externen Klasse mit möglichst wenig Aufwand zu portieren – spricht überhaupt nichts gegen freie Funktionen zur Erweiterung der Funktionalität. Ein gutes Beispiel dafür sind die STL-Algorithmen.
SeppJ schrieb:
Ich sehe da kein Speicherleck.
Das von dir beschriebene Problem tritt auf, wenn man Member zu Klassen ohne virtuellen Konstruktor hinzufügt und diese auch noch über einen Basisklassenzeiger löscht.Das wäre nicht nur ein Memory Leak, sondern undefiniertes Verhalten.
-
rean schrieb:
Damit wirst du dir ein schönes Speicherleck einfangen weil der Destruktor von std::string nicht virtual ist. Außerdem ist die Verwendung von using namespace std; in Header-Dateien auch nicht grad toll.
Ich schrieb:
"Achtung! Das hier ist hingeschmiert."Aber danke für den Hinweis.
-
Wow, danke für all die Antworten

So wie ich das verstanden habe will er erreichen, dass er seinen CString-Client-Code möglichst nicht ändern muss.
Genau so ist es, deswegen ist deine Lösung, Nexus, leider sehr umständlich in meinem Fall

noch eine dritte Möglichkeit: Alles auf std::string zu portieren
Dann muss ich, genau wie beim Lösungsansatz oben, wieder alles umschreiben

C++? Vererbung!
Ich hab mal sowas gemacht:
[...]Danke, ich blick den Code zwar nicht so 100% aber ich versuchs dann mal.
Gibts sonst keine Lösung für das Problem?

Spricht irgendwas dagegen einfach in den standardt Include Files rumzuwerkeln und std::string so zu erweitern?
mfg
-
ChangeMyString schrieb:
Spricht irgendwas dagegen einfach in den standardt Include Files rumzuwerkeln und std::string so zu erweitern?

Portabilität. Ansonsten darfst du natürlich an deiner Standardbibliothek rumschustern wie du willst.
-
Ich verstehe immer noch nicht, warum du dich so an
std::stringfestklammerst. Dessen Schnittstelle nützt dir ja eh nichts, weil die Memberfunktionen beiCStringeine andere Namenskonvention haben, du also doch viel ändern müsstest. Wieso also keine eigene Klasse, diestd::stringenthält und das Interface vonCStringanbietet?Ja, gegen das Verändern der Standardbibliothek spricht die Vernunft. Dein Code wird so maximal unportabel, ist an eine einzige Version gebunden, und kann sogar undefiniertes Verhalten auslösen (denn ein Compiler darf Meta-Informationen über seine Standardbibliothek besitzen, z.B. zu Optimierungs- oder Debugzwecken).
-
Ok vielen Dank für eure Hilfe, ich werd jetzt eine eigene Klasse machen die das Interface von CString anbietet

mfg
-
SeppJ schrieb:
ChangeMyString schrieb:
Spricht irgendwas dagegen einfach in den standardt Include Files rumzuwerkeln und std::string so zu erweitern?

Portabilität. Ansonsten darfst du natürlich an deiner Standardbibliothek rumschustern wie du willst.
Es ist tatsächlich so, dass laut Standard alle Änderungen im Namensraum std:: (mit genau einer Ausnahme) ins Reich des UB definiert werden.
-
Tachyon schrieb:
Es ist tatsächlich so, dass laut Standard alle Änderungen im Namensraum std:: (mit genau einer Ausnahme) ins Reich des UB definiert werden.
Ja, aber praktisch würde das schon funktionieren. Trotzdem ist es natürlich eine schlechte Idee, weil maximal unportabel.
-
ChangeMyString schrieb:
Ok vielen Dank für eure Hilfe, ich werd jetzt eine eigene Klasse machen die das Interface von CString anbietet

Ich würde auch mal im Internet suchen. Vielleicht gibt es Leute, die schon vor dem gleichen Problem gestanden haben. String-Implementierungen gibt es sicher auch Millionen, möglicherweise kommt ja eine deinen Wünschen recht nahe.
-
Nexus schrieb:
ChangeMyString schrieb:
Ok vielen Dank für eure Hilfe, ich werd jetzt eine eigene Klasse machen die das Interface von CString anbietet

Ich würde auch mal im Internet suchen. Vielleicht gibt es Leute, die schon vor dem gleichen Problem gestanden haben. String-Implementierungen gibt es sicher auch Millionen, möglicherweise kommt ja eine deinen Wünschen recht nahe.
Ist die CString-Klasse nicht auch einfach nur ein Klassen-Template? Man könnte sich das Ding ja kopieren und dann zum Funktionieren bringen. *hüstel*
-
@Tachyon: Was ist die Ausnahme?