Erweiterung c++ - string-Memberfunktionen
Hatte ich das Bedürfnis zu tun, eine groß-und Kleinschreibung suchen und finden Sie den folgenden code, die hat den trick
bool ci_equal(char ch1, char ch2)
{
return toupper((unsigned char)ch1) == toupper((unsigned char)ch2);
}
size_t ci_find(const string& str1, const string& str2)
{
string::const_iterator pos = std::search(str1. begin ( ), str1. end ( ), str2.
begin ( ), str2. end ( ), ci_equal);
if (pos == str1. end ( ))
return string::npos;
else
return pos - str1. begin ( );
}
Mich zu Fragen, was es dauern würde, um dieser eine member-Funktion von 'string', so könnte es genannt werden wie diese:
string S="abcdefghijklmnopqrstuv";
string F="GHI";
S.ci_find(F);
Merke ich, dass es viele Probleme mit Fall-Umbauten in nicht-englischen Sprachen, aber das ist nicht die Frage, die mich interessiert.
Seins ein Neuling, ich habe schnell verloren zwischen Containern und Vorlagen.
Gibt es trotzdem, dies zu tun? Könnte mir jemand zeigen Sie mir ein Beispiel für etwas ähnliches?
- Wenn Sie konkret Fragen, ob C++ haben die Erweiterung Methoden wie C#?", dann die spezifische Antwort ist "Nein". Es gibt keine Möglichkeit zum hinzufügen von member-Funktionen, um die tatsächlichen
std::string
Klasse, kurz, hacking Ihre Umsetzung. Das kann nicht sein so schwierig, wie es klingt, aber es ist so schlimm, eine Idee, wie es klingt. - Ach ja, und "Könnte mir jemand zeigen Sie mir ein Beispiel für etwas ähnliches?" - der code, den Sie bereits geschrieben haben, ist die C++-ish Weg, es zu tun. Klassen "erweitert" oder "enhanced", indem Sie nicht-member-Funktionen, die auf Sie einwirken, und C++ - Programmierer sind nicht so verzweifelt in der Liebe mit der
.
Mitglied Funktionsaufruf-syntax, die Sie als ein problem 😉 - Ich möchte vielen Dank an alle, die geantwortet haben, um diese Abfrage. Es scheint die kurze Antwort ist "Nein, es ist unmöglich, andere member-Funktionen string". So, das war der Kern meiner Abfrage habe ich beschlossen, zu akzeptieren, Toms Antwort.
Du musst angemeldet sein, um einen Kommentar abzugeben.
std::string
ist nicht erweitert werden.Könnten Sie Kapseln ein std::string in einer Klasse von Euch-und setzen die Funktionen in dieser Klasse.
Ich denke, die meisten erfahrenen C++ - Programmierer würden Zustimmen, dass dies schlechte Idee. Wenn überhaupt, dann
std::string
hat schon viel zu viele member-Funktionen, und das hinzufügen von noch mehr machen eine schlechte situation noch schlechter. Schlimmer noch, wenn Sie im Begriff waren, dies zu tun, würden Sie wahrscheinlich tun es durch Vererbung -- aberstd::string
ist nicht entworfen, um als eine Basis-Klasse, und verwenden Sie es als eine führt zu code, der fragil und fehleranfällig.Für eine andere Idee, wie dies zu tun, möchten Sie vielleicht zu Lesen Guru der Woche #29. Lesen Sie den ganzen Artikel ist jedoch, eine Vorstellung davon zu bekommen, wie es zu tun, und, warum Sie wollen wahrscheinlich nicht zu. Letztlich, was Sie jetzt haben, ist wahrscheinlich die beste option -- halten Sie die groß /Kleinschreibung bei der Suche getrennt von
std::string
selbst.std::basic_string
dient nicht vererbt werden, da es nicht über einen virtuellen Destruktor und so eine polymorphe Löschung einer Instanz der erweiterten Klasse (nennen wir esstringex
) mit einembasic_string
Zeiger würde Auslaufen, weilstringex
's Destruktor nicht aufgerufen. Aber was ist, wennstringex
nicht brauchen, und nicht selbst definieren ein Destruktor, weil alle, die diese Klasse enthält, werden native Typen und weitere member-Funktionen, kein memory-Allokation. Ist es immer noch ein problem in diesem Fall?basic_string
's, die aufgerufen werden soll wenn derstringex
Objekt gelöscht wird mit einembasic_string
Zeiger, unabhängig davon, ob letztere hat einevirtual
Destruktor oder nicht. Oder ist der Undefinierte Bestandteil der üblichen Verwendung Fall, wo es nicht definiert ist, obstringex
's Destruktor rufenbasic_string
's Destruktor?operator delete
ist nicht das gleiche wie der zurück durchoperator new
es sei denn, Sie verfügen entweder über einen virtuellen Destruktor zu löschen oder die abgeleitete Objekt.char_traits
parameter ersetzt case-sensitive Verhalten mit der groß-und Kleinschreibung. Auf die groß-und Kleinschreibungfind
auf eineci_string
eine freie Funktion nötig wäre... schließt sich der Kreis.std::string *s = new stringex; delete s;
mit einem non-virtual-dtor. Sie würde wahrscheinlich nicht absichtlich, aber wenn Sie mit öffentlicher Vererbung, der compiler ermöglicht die implizite Konvertierung von der abgeleiteten zur Basisklasse -- was macht einen Unfall ziemlich einfach. Es ist unbestimmt, weil mit ihm nicht-virtuellen, der compiler funktioniert wie gewohnt, und ruft dtor basierend auf dem Typ des Zeigers statt, die den Typ des Objekts Punkte an. Versuchen, heraus zu Sortieren, wenn das wäre sicher nicht lohnend, so dass es immer UB.string
es ist schwerer zu sagen-als eine stark genutzte Bibliothek-Klasse, es gibt eine Menge motivation, es zu optimieren, möglicherweise in einer Weise, die zu Problemen führen könnte, würden Sie normalerweise nicht begegnen. 3. Beide Holen Sie genannt-zunächst abgeleitet, dann base. 4. ja, es geschieht automatisch.Vielleicht nach den Standard-Algorithmen-Bibliothek
<algorithm>
Methodik von Vorteil sein könnte. Es würde nicht überraschen, die Benutzer so viel. 🙂Algorithmus-Funktionen als ein Beispiel.
ci_find
zeigt, wenn er diese als Algorithmus wäre es nur eine leichte Variante desstd::search
mit einem besonderen Prädikat.Meisten der Zeit, es wird ausreichen, um zu definieren, eine Funktor.genauer gesagt, eine weniger als Komparator. Der Vorteil ist, dass die functor, zusammen mit der unverändert
string
Klasse, kann gespeichert werden in STL-Containern und STL verwenden Ihre benutzerdefinierten funktoren für Operationen.Ist es eine Klasse mit einem Standardkonstruktor und einen überladenen Funktions-Aufruf-operator
bool operator()(const string& x, const string& y)
die führt die groß- /Kleinschreibung-Vergleich.
können Sie definieren auch eine Gleichstellung Funktor, je nach Ihrem Bedarf.Wahr, es ist nicht mehr möglich, die
==
und<
Betreiber buchstäblich auf Objekte Ihrer Klasse string, stattdessen müssen Sie erstellen eine Instanz von functor und verwenden Sie es wie eine Funktion aufrufen. Aber ich glaube nicht, dass es keine andere alternative in C++.Bearbeitet: ich habe falsch verstanden, die Frage. Der nicht relevante Teil der Antwort ist, entfernt.
Bearbeitet 2: Bitte komplett ignorieren meine Antwort ...
stristr
,wcsistr
etc. (2) wenn Sie gehen, um schreiben Sie Ihre eigene, stellen Sie sicher, dass Sie verstehen, Knuth-Morris-Pratt und Boyer-Moore algorithmen. (3) stellen Sie sicher, dass Sie verstehenchar_traits
. Wie @Potatoswatter darauf hingewiesen, Ihre groß-und Kleinschreibungchar_traits
dürfen nicht verwendet werden, um sich zu spezialisierenbasic_string
, sondern wird verwendet, um sich zu spezialisieren, Ihre KMP oder BM - Implementierung. Es ist nicht trivial, so versuchen Sie härter auf der Suche für eine bestehende Anwendung oder verwenden Sie Ihre aktuelle.basic_string
Klasse.