Używam C i struct
s, gdzie struct może mieć członków, ale nie funkcje. Załóżmy dla uproszczenia, że chcę utworzyć strukturę dla ciągów, które nazywam str
i chcę być w stanie zrobić, str.replace(int i, char c)
gdzie i
jest indeks ciągu i c
jest on znakiem zastępującym znak w miejscu i
. Czy nigdy nie byłoby to możliwe, ponieważ struktury nie mogą mieć funkcji lub istnieje sposób, w jaki możemy wdrożyć to zachowanie i naśladować, że struktura może mieć (prostą) funkcję, która w rzeczywistości jest tylko strukturą kopiującą się do nowej struktury i aktualizującą jej pola, które mógłby zrobić?
Więc replace
może być trzecim członkiem struct że punkty do nowej struktury, która jest aktualizowana, gdy jest ona dostępna lub podobny. Czy można to zrobić? Czy jest coś wbudowanego, teorii lub paradygmatu, który uniemożliwia mi zamiar?
Tło jest takie, że piszę kod C i odkrywam, że odkryłem na nowo funkcje, które są wbudowanymi bibliotekami w językach OOP i że OOP byłby dobrym sposobem na manipulowanie ciągami i poleceniami.
źródło
str.replace(&str, i, c)
inaczej.this
Oczywiście C ++ automatyzuje przekazywanie wskaźnika.Odpowiedzi:
Twoja funkcja powinna wyglądać tak.
To akceptuje wskaźnik do obiektu, który ma działać jako pierwszy parametr. W C ++ jest to znane jako
this
-pointer i nie musi być jawnie deklarowane. (Porównaj to z Pythonem tam, gdzie musi).Aby wywołać twoją funkcję, przekazałeś również ten wskaźnik jawnie. Zasadniczo wymieniasz
o.f(…)
składnię naf(&o, …)
składnię. Nic takiego.Historia staje się bardziej wciągająca, jeśli chcesz wspierać polimorfizm (aka
virtual
funkcje). Można go również emulować w C (pokazałem to dla tej odpowiedzi .), Ale nie jest to łatwe ręcznie.Jak skomentował Jan Hudec , powinieneś również przyzwyczaić się poprzedzać nazwę funkcji nazwą typu (tj.
string_replace
), Ponieważ C nie ma przestrzeni nazw, więc można nazwać tylko jedną funkcjęreplace
.źródło
string_replace
, ponieważ C również nie ma przeciążenia funkcji i prawdopodobnie masz jakieś innereplace
dla innego typu…string_replace
. Nazwy rozpoczynające się odstr
,mem
lubwcs
poprzedzające małą literę są zarezerwowane dla przyszłych rozszerzeń.Struktury mogą przechowywać wskaźniki funkcji , ale tak naprawdę są one potrzebne tylko w przypadku metod wirtualnych. Nie-wirtualne metody w obiektowym C są zwykle wykonywane przez przekazanie struktury jako pierwszego argumentu do funkcji regularnej. Spójrz na Gobject na dobry przykład frameworka OOP dla C. Korzysta on z makr do obsługi wielu elementów kotłowych wymaganych do dziedziczenia i polimorfizmu.
C powstał 44 lata temu. Jest to bardzo popularny język dla open source. Nie jesteś pierwszą osobą, która uważa, że standardowe ciągi C są niezręczne w pracy. Wyszukaj biblioteki ciągów C. Nie musisz wymyślać koła od nowa.
źródło
Za pomocą wskaźników funkcji możesz:
Jest to na ogół przydatne tylko wtedy, gdy implementacja może się zmienić, w takim przypadku powinieneś użyć vtable, aby narzut był tylko jednym wskaźnikiem na strukturę:
źródło
str
(lubmem
lubwcs
) i małe litery są zarezerwowane przez standard C dla przyszłych rozszerzeń, więc nie nazywaj gostring_replace
.str_replace
jest w porządku.Tak, mogą. Możesz skorzystać z faktu, że C pozwala wskaźnikom na funkcjonowanie bloków w pamięci, czyli wskaźników funkcji, i korzystając z tego, możesz stworzyć interfejs, taki jak polimorfizm, a także funkcje wirtualne (nawet jeśli nie jest to tak ładne).
Napisałem post na blogu na ten temat, w odpowiedzi na pytanie jednego z moich studentów, dotyczące kodu podobnego do interfejsu w C i Go, możesz przeczytać tutaj:
Wpis na blogu o interfejsach innych niż OO
Sprawdź, czy to daje jakieś pomysły.
Możesz także po prostu umieścić w kodzie darmową funkcję i użyć wskaźnika „this”, co oznacza, że przekazujesz wskaźnik do istniejącej struktury, aby pracować, jak opisano w innych odpowiedziach.
źródło