Ich benutze C und struct
s, wobei eine Struktur Mitglieder haben kann, aber keine Funktionen. Nehmen wir der Einfachheit halber an, dass ich eine Struktur für Zeichenfolgen erstellen möchte, die ich benenne, str
und dass ich tun möchte, str.replace(int i, char c)
wo i
sich der Index der Zeichenfolge befindet und welches c
Zeichen das Zeichen an der Position ersetzen soll i
. Wäre dies niemals möglich, da Strukturen keine Funktionen haben können oder gibt es noch eine Möglichkeit, dieses Verhalten zu implementieren und nachzuahmen, dass eine Struktur eine (einfache) Funktion haben könnte, die eigentlich nur darin besteht, dass die Struktur sich selbst in eine neue Struktur kopiert und diese aktualisiert Felder, was könnte es tun?
Könnte replace
also ein drittes Mitglied der Struktur sein, das auf eine neue Struktur verweist, die aktualisiert wird, wenn darauf zugegriffen wird, oder ähnliches. Könnte es gemacht werden? Oder gibt es etwas Eingebautes oder eine Theorie oder ein Paradigma, das meine Absicht verhindert?
Der Hintergrund ist, dass ich C-Code schreibe und Funktionen neu erfinde, von denen ich weiß, dass sie in OOP-Sprachen eingebaute Bibliotheken sind und dass OOP eine gute Möglichkeit ist, Zeichenfolgen und Befehle zu manipulieren.
quelle
str.replace(&str, i, c)
sowieso am Ende sind .this
Natürlich automatisiert C ++ die Übergabe des Zeigers.Antworten:
Ihre Funktion sollte so aussehen.
Dies akzeptiert einen Zeiger auf das zu bearbeitende Objekt als ersten Parameter. In C ++ wird dies als
this
-pointer bezeichnet und muss nicht explizit deklariert werden. (Vergleichen Sie dies mit Python, wo es sein muss.)Um Ihre Funktion aufzurufen, würden Sie diesen Zeiger auch explizit übergeben. Grundsätzlich tauscht man die
o.f(…)
Syntax gegen dief(&o, …)
Syntax. Keine große Sache.Die Geschichte wird mehr involviert, wenn Sie Polymorphismus unterstützen möchten (aka
virtual
Funktionen) . Es kann auch in C emuliert werden (ich habe es für diese Antwort gezeigt .), Aber es ist nicht schön, von Hand zu tun.Wie Jan Hudec kommentiert hat, sollten Sie es sich auch zur Gewohnheit machen, dem Funktionsnamen den Typnamen (dh
string_replace
) voranzustellen, da C keine Namensräume hat, so dass es nur eine einzige benannte Funktion geben kannreplace
.quelle
string_replace
, da C auch keine Funktionsüberladung hat und Sie wahrscheinlich eine anderereplace
für einen anderen Typ haben werden ...string_replace
. Namen, die mitstr
,mem
oderwcs
gefolgt von einem Kleinbuchstaben beginnen, sind für zukünftige Erweiterungen reserviert.Structs können Funktion halten Zeiger , aber die sind wirklich nur für virtuelle Methoden benötigt. Nicht virtuelle Methoden in objektorientiertem C werden normalerweise ausgeführt, indem die Struktur als erstes Argument an eine reguläre Funktion übergeben wird. Ansehen Gobject an, um ein gutes Beispiel für ein OOP-Framework für C zu finden. Es verwendet Makros, um einen Großteil der für Vererbung und Polymorphie erforderlichen Boilerplates zu verarbeiten.
C wurde vor 44 Jahren erstellt. Es ist eine sehr beliebte Sprache für Open Source. Sie sind nicht die erste Person, die der Meinung ist, dass die Arbeit mit Standard-C-Zeichenfolgen schwierig ist. Suchen Sie nach C-String-Bibliotheken. Sie müssen das Rad nicht neu erfinden.
quelle
Mit Funktionszeigern können Sie Folgendes tun:
Dies ist im Allgemeinen nur sinnvoll, wenn sich die Implementierung ändern kann. In diesem Fall sollten Sie eine vtable verwenden, damit der Overhead nur einen Zeiger pro Struktur darstellt:
quelle
str
(odermem
oderwcs
) beginnen, und Kleinbuchstaben werden vom C-Standard für zukünftige Erweiterungen reserviert. Nennen Sie sie daher nichtstring_replace
.str_replace
ist gut.Ja, das können sie. Sie können die Tatsache ausnutzen, dass C Zeiger auf Funktionsblöcke im Speicher zulässt, auch als Funktionszeiger bezeichnet, und damit Schnittstellen wie Polymorphismus sowie virtuelle Funktionen erstellen (auch wenn sie nicht so hübsch sind).
Ich habe einen Blogbeitrag zu diesem Thema verfasst, der auf eine Frage eines meiner Studenten hin kürzlich zum schnittstellenähnlichen Code in C und Go verfasst wurde. Sie können ihn hier lesen:
Blogbeitrag zu Nicht-OO-Schnittstellen
Sehen Sie nach, ob es Ihnen Ideen gibt.
Sie können auch einfach eine freie Funktion in Ihren Code einfügen und einen "this" -Punkt verwenden. Dies bedeutet, dass Sie einen Zeiger auf eine vorhandene Struktur übergeben, an der gearbeitet werden soll, wie in den anderen Antworten beschrieben.
quelle