Kiedy pojawiają się „funkcje statyczne”?

25

OK, nauczyłem się czym jest funkcja statyczna, ale wciąż nie rozumiem, dlaczego są one bardziej użyteczne niż prywatne funkcje członka. To może być trochę nowe pytanie, ale dlaczego zamiast tego po prostu zastąpić wszystkie prywatne funkcje składowe funkcjami statycznymi?

Mroczny Templariusz
źródło
1
Czy nie powinno to oznaczać „zastąpienia wszystkich funkcji statycznych funkcjami członka prywatnego”? Obecnie twierdzisz, że nie widzisz sensu metod statycznych, i pytasz, dlaczego nie używamy ich więcej.
5
Co to jest „funkcja statyczna”? W C ++ istnieją co najmniej dwa znaczenia (a ostatnio patrzyłem na wersje robocze C ++ 11, usunęły one informację o wycofaniu staticdla ograniczania funkcji do zakresu pliku.
David Thornley,
Czy masz na myśli „funkcję statyczną” w znaczeniu funkcji statycznej bez zakresu w zakresie plików w C / C ++, czy jako „funkcję / metodę statycznego członka”? To ogromna różnica!
Jan Hudec
@JHHec: Myślę, że biorąc pod uwagę obecność private membermożemy bezpiecznie założyć, że OP pyta o koncepcję OO i nie ma pojęcia o statycznym zakresie pliku.
Matthieu M.,
@MatthieuM .: Właściwie obecność „członka prywatnego” właśnie mnie przekonała, że ​​ma on na myśli funkcje statyczne w sensie C ++. Ponieważ funkcje statyczne o zasięgu pliku i funkcje prywatnych członków są dwiema rzeczami, które mają bardzo podobne zastosowanie w C ++, podczas gdy zamiana publicznego członka statycznego na prywatny element niestatyczny po prostu nie ma większego sensu. Niestety OP wydaje się nie odpowiadać.
Jan Hudec

Odpowiedzi:

25

Zakładając, że używasz OOP , używaj funkcji statycznych, gdy nie zależą one od żadnych członków klasy. Nadal mogą być prywatne, ale w ten sposób są zoptymalizowane, ponieważ nie zależą od żadnego wystąpienia powiązanego obiektu.

Poza powyższym uważam, że funkcje statyczne są przydatne, gdy nie chcesz tworzyć instancji obiektu tylko po to, aby wykonać na nim jedną funkcję publiczną. Dzieje się tak głównie w przypadku klas pomocników, które zawierają funkcje publiczne, aby wykonywać powtarzalne i ogólne prace, ale nie muszą utrzymywać żadnego stanu między wywołaniami.

Bernard
źródło
Dziękuję Bernard. A tak przy okazji, czy wiesz, co to znaczy, że kompilator „wiąże metodę z klasą”?
Dark Templar,
@Dark Templar: Nie mogę tego powiedzieć. Czy jest to specyficzne dla konkretnego języka?
Bernard,
Mam niewielki problem z twoją definicją „nie zależą od żadnych członków klasy”. Funkcje statyczne elementu nie mogą uzyskać dostępu do żadnego elementu niestatycznego, ale mogą uzyskać dostęp do elementów statycznych. Członkowie statyczni są członkami klasy.
newprint
@newprint: Masz rację, ale nie to powiedziałem. Powiedziałem, kiedy nie zależą od żadnych członków klasy. Używanie elementów statycznych jest w porządku, jeśli są konieczne, ale nie zawsze tak jest.
Bernard,
8

Próbuję znaleźć bardziej uproszczone wyjaśnienie niż powyższe (całkiem dobre).

Obiekt jest normalnie kodem + danymi. Metoda statyczna jest używana, gdy masz do czynienia tylko z częścią „kodową” (nie zachowuje się danych / stanu (z wyjątkiem elementów danych statycznych)).

Brian Knoblauch
źródło
5

Ponieważ nie wymagają wystąpienia i mogą być publiczne. Załóżmy, że potrzebujesz funkcji, aby uzyskać największy wspólny mianownik (GCD; bardzo przydatne dla klas ułamkowych; i tak, to tylko prosty przykład). Nie ma sensu tworzenie klasy obiektów, których jedynym celem jest posiadanie thiswskaźnika, którego nie potrzebujesz ani nie używasz gcd. Używasz do tego metody statycznej, najlepiej w klasie, która faktycznie używa GCD (np. W klasie ułamkowej).

Jeśli masz tylko metody statyczne, robisz OOP źle i powinieneś albo przejść do robienia OOP, albo używać języka bardziej odpowiedniego dla twojego paradygmatu.

użytkownik7043
źródło
Czy w twoim przykładzie nie byłoby lepiej korzystać z darmowej funkcji?
Ela782
2
@ Ela782 Jeśli język ma darmowe funkcje, tak.
OK, dziękuję za zapewnienie. Niedawno nauczyłem się tej najlepszej praktyki. Jednak w tej chwili mam problemy ze stwierdzeniem, kiedy publiczna statyczna funkcja składowa może być rzeczywiście przydatna, powiedzmy w języku takim jak C ++. Przypadek użycia dla obu jest taki, gdy funkcja nie zależy lub nie potrzebuje instancji klasy, a następnie zalecane są funkcje bezpłatne. Może to powinno być nowe pytanie.
Ela782
1
@ Ela782 Tak, może to być dobre pytanie. Dwa szybkie punkty: W szczególności w C ++ elementy statyczne są przydatne do meta programowania szablonów, ponieważ można przekazać typ jako parametr szablonu, ale nie przestrzeń nazw. Ogólnie rzecz biorąc, można użyć funkcji statycznych, aby wskazać, że funkcja naprawdę bardzo należy do jakiejś klasy, w przeciwieństwie do samej przynależności do przestrzeni nazw (think stuff::Thing::Load(...)vs stuff::LoadThing()).
2

Używam ich jako funkcji pomocniczych do typowych zadań, na przykład:

  • Przeliczanie stopni na radiany (i odwrotnie);
  • Hashowanie sznurka;
  • Przekształcanie z wyliczenia na coś innego (w tym projekcie pracuję, działają jak tablica skrótów);

Większość moich plików, które grupują funkcje statyczne, ma przyrostek Helper, co oznacza, że ​​to, co robią, pomaga mi dostać się gdzieś szybciej.

George Silva
źródło
2

Co do metody statycznej:

Metody statyczne nie wymagają instancji klasy ani nie mogą pośrednio uzyskiwać dostępu do danych (lub tego, self, Me itp.) Takiej instancji. [ 1 ]

Przykłady kiedy przydatne są metody statyczne:

  • Metody globalne / pomocnicze
  • Pobieranie wyników zapytania z klasy modelu danych (wywoływanie SP)

Używaj ich tylko w razie potrzeby.

  1. Jeśli okaże się, że kopiujesz te same metody w wielu obiektach, rozważ ustawienie metody na statyczną, abyś mógł śledzić OSUSZANIE.
  2. Użyj metod statycznych, jeśli nie potrzebujesz instancji obiektu (nie pracujesz nad zmiennymi instancji obiektu)

Jeśli wiele danych znajduje się poza obiektami i są one przetwarzane metodami statycznymi, kod nie jest zorientowany obiektowo i może być trudny w utrzymaniu.

koder
źródło
1

Statyczne i prywatne są w rzeczywistości ortogonalne: metoda może być statyczna lub prywatna, albo żadna, albo obie.

Statyczne vs. niestatyczne (znane również jako „metody instancji”) wskazują, czy metoda działa na samej klasie (statyczna), czy na konkretnej instancji (niestatyczna). W zależności od języka można wywołać metodę statyczną za pośrednictwem instancji, ale nigdy nie można uzyskać dostępu do instancji za pomocą metody statycznej (co oznacza również, że nie można wywoływać żadnych metod niestatycznych z wnętrza metody statycznej, po prostu dlatego, że nie ma thisobiekt). Użyj metod statycznych, aby zaimplementować zachowanie, które jest koncepcyjnie powiązane z klasą, ale nie „wiąże się” z jedną konkretną instancją. Innym scenariuszem, w którym możesz chcieć użyć metod statycznych jest sytuacja, w której masz funkcję działającą na dwóch instancjach klasy i żaden operand nie zasługuje na uprzywilejowany status - na przykład zakładając, że masz klasęVector, a chcesz wdrożyć dodawanie; twoją metodę dodawania można nazwać jako a.Add(b), ale Vector.Add(a, b)prawdopodobnie ma to większy sens.

Prywatne vs. publiczne dotyczą widoczności metody. Do metod prywatnych można uzyskać dostęp wyłącznie z zakresu klasy, podczas gdy metody publiczne są dostępne z dowolnego miejsca. Najważniejszym zastosowaniem do tego jest enkapsulacja: upubliczniając tylko te metody i właściwości, które są absolutnie potrzebne reszcie kodu do komunikowania się z klasą, ograniczasz punkty, w których kod zewnętrzny może wprowadzać problemy i zapobiegasz problemom wewnątrz twoja klasa od krwawienia do reszty projektu.

Zatem zasada praktyczna:

  • ustaw wszystkie funkcje składowe jako prywatne, z wyjątkiem tych, które muszą być wywoływane spoza klasy
  • uczyń wszystkie metody metodami instancji, chyba że mają sens, nawet jeśli nie istnieje żadna instancja klasy
tdammers
źródło
0

Używam metod statycznych zarówno w C ++, jak i C # dla klas Utility, klas, które nie mają żadnych danych instancji, tylko jeden sposób na spakowanie kolekcji przydatnych, powiązanych metod.

int count1 = DBUtil::GetCountOfSlackerEmployees();
int count2 = DBUtil::GetCountOfEmployedSlackers();
Chris O
źródło
0

Zakładając, że mówisz o C ++ (nie powiedziałeś) i masz odpowiednie terminy (tj. Nie oznacza to funkcji / metod członkowskich):

Nawet prywatna funkcja członka musi jeszcze zostać zadeklarowana w nagłówku, co oznacza, że ​​faktycznie staje się ona częścią API i ABI klasy, nawet jeśli użytkownik nie może tak naprawdę jej wywołać. Jeśli dodajesz, modyfikujesz lub usuwasz funkcję członka prywatnego, wymuszasz ponowną kompilację wszystkich klas zależnych (nagłówek zmienił się, nie można lepiej wiedzieć), a kiedy to robisz w bibliotece, musisz rozważyć kompatybilność aplikacji przy to.

Z drugiej strony funkcje statyczne o zasięgu pliku nie otrzymują publicznego symbolu, więc możesz je dodawać, modyfikować lub usuwać, jak chcesz, i nic poza jednostką kompilacji nigdy nie zostanie zmienione.

Jan Hudec
źródło
0

Zazwyczaj potrzebujesz statycznego elementu głównego, który będzie działał jako punkt wejścia do programu. To może być trochę ważne.

Wyatt Barnett
źródło
0

Funkcja statyczna (i różne znaczenia tego terminu w różnych językach), nie wymaga żadnego stanu, który jest zachowywany między rozmowami. Jeśli jest koncepcyjnie ściśle związany z tym, co robi klasa, uczyń ją funkcją klasy (tak jak w klasie, a nie obiektem), a jeśli nie, uczyń ją funkcją globalną (lub na poziomie modułu, cokolwiek). Nie należy do obiektu, jeśli nie potrzebuje stanu obiektu.

Jeśli cały czas przekazujesz mu stan, to tak naprawdę nie jest to funkcja bezstanowa, po prostu tworzysz funkcję stanową ze składnią bezstanową. W takim przypadku prawdopodobnie należy on do obiektu wywołującego, a może refaktoryzacja w celu lepszego wyrównania stanu i wskazane zachowanie

Kylben
źródło
0

„dlaczego nie zastąpić w zamian wszystkich funkcji członka prywatnego funkcjami statycznymi?”

... ponieważ członek prywatny może uzyskiwać dostęp do danych instancji, pozwalając na to tylko z wywołań wykonywanych w ramach innych funkcji członka. Funkcja statyczna może być prywatna, ale nie będzie mogła zmieniać ani odwoływać się do instancji klasy, chyba że instancja zostanie przekazana jako parametr.

jheriko
źródło
0

To zabawne, że nikt nie był jeszcze w stanie udzielić dobrej odpowiedzi. Nie jestem pewien, czy to też jest. Prawdopodobnie powinieneś potraktować to jako wskazówkę, że należy ich używać tak mało, jak to możliwe. Są przecież raczej proceduralne niż OOP.

Oto kilka innych przykładów:

W Obj-C, gdzie są nazywane metodami klasowymi, są one powszechnie używane jako opakowania alokacji, w których obiekt jest umieszczany w puli liczenia referencji przed zwróceniem.

Innym przykładem z Obj-C jest zarejestrowanie nowej klasy w kolekcji klas. Załóżmy, że masz zestaw klas, z których każda obsługuje jeden typ pliku. Gdy tworzysz nową klasę dla nowego typu pliku, możesz zarejestrować ją w kolekcji (zmienna globalna) przy użyciu metody statycznej w klasie, która określa typ pliku.

W C ++ innym sposobem, jaki mogę wymyślić, jest miękkie wychwytywanie błędów. Twoja funkcja konstruktora nie może zawieść, z wyjątkiem zgłoszenia wyjątku. Można ustawić zmienną wystąpienia błędu, ale nie zawsze jest to właściwe. Zamiast tego możesz wykonać części, które mogą zawieść w statycznym opakowaniu, a następnie przydzielić i zwrócić nowy obiekt lub NULL w przypadku awarii.

Per Johansson
źródło
0

Powiedzmy, że chcesz obliczyć sinus czegoś.

Bez zakłóceń:

Math math = new Math()
double y = math.sin(x)

Ze statycznym:

double y = Math.sin(x)

Nie ma sensu robić sinniestatycznych. Jest bezstanowy i po prostu przetwarza dane wejściowe.

Funkcje statyczne nie są powiązane z konkretnymi obiektami. Są to „ogólne” funkcje, które są niezależne od wewnętrznego stanu obiektu.

Dagnele
źródło
Metody statyczne nie są „gwarantowane jako bezpaństwowe”. Chociaż prawdą jest, że nie mogą korzystać z danych instancji, mają również dostęp do niektórych stanów (mianowicie elementów statycznych, zarówno klasy, do której należy metoda statyczna, jak i do innych globalnie widocznych stanów, takich jak zmienne statyczne innych klas).
@delnan: true ... masz rację. Pozwól mi to teraz poprawić.
Dagnelies
Bez tłoczenia: x.sin(). Twoja odpowiedź zakłada, że ​​grzech powinien być funkcją „matematyki”, podczas gdy wyraźnie działa na podwójny.
AjahnCharles
0

Trochę tu późno, ale chciałbym spróbować stworzyć dokładną definicję: funkcje statyczne to funkcje, które nie odwołują się do właściwości instancji / metod klasy zawierającej lub nie mogą do nich odwoływać.

W niektórych językach, takich jak C #, mogą istnieć pola statyczne lub właściwości w klasach statycznych, więc nie jest właściwe twierdzenie, że nie są używane do stanu; funkcja statyczna może wykorzystywać stan statyczny (globalny).

Zasadniczo sprowadza się on do: funkcji statycznych, podobnie jak innych statycznych, są przydatne, gdy ma sens, aby zawsze były dostępne bez zależności od instancji niestatycznych.

Funkcje pomocnicze, podobnie jak funkcje matematyczne, są częstym przykładem, ale są też inne.

Jeśli tworzona klasa wymaga, aby dane były niezmienne, sensowne może być utworzenie funkcji statycznych, które przyjmują instancję i przekazują nową instancję, ponieważ instancji nie można (lub nie należy) zmieniać. Na przykład klasy ciągów mogą mieć funkcje statyczne, które pobierają ciąg (lub 2 lub więcej) i przekazują nowy ciąg.

Innym powodem może być to, że istnieje klasa, która utrzymuje pewien stan globalny lub dane. Mogą istnieć funkcje statyczne, które działają z właściwościami statycznymi lub polami w tej klasie statycznej.

Kok
źródło
0

Chciałbym zwrócić uwagę na inne zastosowanie statycznego f ().

http://www.parashift.com/c++-faq/named-ctor-idiom.html

Sprowadza się do tego: staticfunkcje pozwalają na tworzenie „Nazwanych konstruktorów”, tzn. Nazywasz swoją funkcję statyczną odpowiednią i samowydajną nazwą, a ta funkcja statyczna wywołuje jednego z konstruktorów (ponieważ konstruktory mają identyczne nazwy i możesz mieć wielu z nich, trudno jest je rozróżnić).

nowy odcisk
źródło