std::string operator= überladen/erweitern
-
Guten Morgen.
Ich möchte gerne meine eine String Klasse AbcString dem std::string mittels operator= zuweisen, ist das möglich?
class AbcString { private: // irgendwelche Member-Variablen public: AbcString() ~AbcString() AbcString& operator=(const AbcString& src); AbcString& operator=(const std::string& src); };
Damit man den std::string::operator= erweitern kann, habe ich mir gedacht, dass man dies außerhalb der Klasse machen muss und einfach darunter folgendes geschrieben:
std::string& operator=(std::string &str, const XString& xstr);
Das funktioniert leider nicht.
Gibt es überhaupt die Möglichkeit, dass man std::string so erweitert, dass dies möglich ist?DANKE für eure Hilfe!!
LG Ric
-
"Funktioniert nicht " - aha.
-
sollte natürlich so heißen:
std::string& operator=(std::string &str, const AbString& abcstr);
Und der Compiler spuckt das hier aus:
error: ‘std::string& operator=(std::string&, const AbString&)’ must be a nonstatic member function
-
Zuweisungsoperatoren müssen Member sein.
-
MFK schrieb:
Zuweisungsoperatoren müssen Member sein.
Hmm, aber dann müsste ich std::string erweitern, oder? Nur wie ist das möglich?
-
str_overload schrieb:
MFK schrieb:
Zuweisungsoperatoren müssen Member sein.
Hmm, aber dann müsste ich std::string erweitern, oder? Nur wie ist das möglich?
Gar nicht.
Mach aus Deinem String einen
std::string
:class AbcString { ... public: operator std::string() { ... } };
-
DANKE Furble Wurble!
So funktioniert es nun!
class AbcString { private: // irgendwelche Member-Variablen public: AbcString() ~AbcString() const char* Get(); int GetSize(); operator std::string() { return std::string(Get(), GetSize); } };
Darf man Fragen wie es in diesem Fall auch noch bzgl. der Performance aussieht?
AbcString abc; std::string str; str = abc;
Kann hier der Compiler das so optimieren, dass nicht unnötig Speicher angelegt und wieder freigegeben werden muss?
Oder wäre dies hier doch besser bzw. am schnellsten:
str.assign(abcstring.Get(), abcstring.GetSize());
-
str_overload schrieb:
Kann hier der Compiler das so optimieren, dass nicht unnötig Speicher angelegt und wieder freigegeben werden muss?
Ja. Das ist sogar ausdrücklich erlaubt, selbst wenn die wegoptimierte Kopie beobachtbares Verhalten beinhalten würde. Ansonsten wären Rückgabewerte praktisch unbenutzbar.
-
@SeppJ
Danke für die Info. Muss man da etwas bestimmtes beachten, damit das so funktioniert?Habe gerade einen Test gemacht (gcc 4.8.2, core2Duo, Ubuntu 14.04LTS) und folgende Erkenntnis bekommen bei 10.000.000 durchläufen
- Zuweisung mittels assign 30,369sec (c++11 30,318sec)
- Zuweisung mittels operator 34,092sec (c++11 29,875sec)
-
str_overload schrieb:
@SeppJ
Danke für die Info. Muss man da etwas bestimmtes beachten, damit das so funktioniert?Es kann (nicht muss!) für den Compiler schwer werden, wenn man verschiedene, benannte Objekte zurück gibt:
string foo(bool foo) { string a = "a"; string b = "b"; if (foo) return a; else return b; }
-
Damit man den std::string::operator= erweitern kann, habe ich mir gedacht, dass man dies außerhalb der Klasse machen muss und einfach darunter folgendes geschrieben:
Nein, das ist nicht möglich, und aus gutem Grund. U.a. weil der Zuweisungsoperator eine spezielle Memberfunktion ist - buchstäblich, nach Definition. Und er spielt eine entscheidende Rolle bei der Definition von anderen wichtigen Dingen, e.g. ob ein Move-Konstruktor implizit deklariert wird, oder ob eine Klasse trivial [kopierbar] ist, etc.
Habe gerade einen Test gemacht (gcc 4.8.2, core2Duo, Ubuntu 14.04LTS) und folgende Erkenntnis bekommen bei 10.000.000 durchläufen
Optimierungslevel? Und hast du volkards Messmethode angewandt? Ohne deinen Code sind die Ergebnisse praktisch nutzlos.
-
SeppJ schrieb:
Es kann (nicht muss!) für den Compiler schwer werden, wenn man verschiedene, benannte Objekte zurück gibt
Die Zuweisung mittels assign sieht so aus:
str.assign(abcstring.Get(), abcstring.GetSize());
die Zuweisung mittels operator so (bzw. der opterator an sich):
str = xstring; // Zuweisung ... operator std::string() const // operator in AbcString-Klasse { return std::string(Get(), GetSize()); }
Arcoth schrieb:
Optimierungslevel?
-O2
Arcoth schrieb:
Und hast du volkards Messmethode angewandt?
Leider sagt mir diese Messmethode nichts. Ich habe mir vor langer langer Zeit selbst eine Stopwatch gemacht mittels clock_gettime(CLOCK_MONOTONIC, &tp);
Arcoth schrieb:
Ohne deinen Code sind die Ergebnisse praktisch nutzlos.
reichen die oben gemachten code-Ausschnitte aus? Weil mehr als eben meine "stoppwatch" Rundherum habe ich auch nicht.