Tak. W dawnych czasach nazywaliśmy to „funkcją”. Dzieciaki dzisiaj z waszymi szalonymi „przestrzeniami nazw”. Hej, zejdź z mojego trawnika! <potrząsa pięścią
włóczęga
7
@ Vagrant funkcja w przestrzeni nazw jest nadal funkcją. Funkcja należąca do klasy nazywana jest metodą. Jeśli jest to metoda statyczna, wywołujesz ją podobnie, jakby była funkcją wewnątrz przestrzeni nazw.
48
5 lat później i teraz jestem po stronie @Vagrant. Co za głupie pytanie!
andrewrk
16
9 lat później, a teraz mam swój własny język programowania, który nawet nie ma zajęć: ziglang.org
andrewrk 30.09.17
1
W niektórych przypadkach przydatne są klasy kontenerowe IMO (posiadające tylko metody statyczne).
AarCee
Odpowiedzi:
272
Jeśli szukasz sposobu zastosowania słowa kluczowego „static” do klasy, jak na przykład w C #, nie będziesz w stanie tego zrobić bez użycia Managed C ++.
Ale wygląd próbki wystarczy utworzyć publiczną metodę statyczną na obiekcie BitParser. Tak jak:
BitParser.h
classBitParser{public:staticbool getBitAt(int buffer,int bitIndex);// ...lots of great stuffprivate:// Disallow creating an instance of this objectBitParser(){}};
BitParser.cpp
boolBitParser::getBitAt(int buffer,int bitIndex){bool isBitSet =false;// .. determine if bit is setreturn isBitSet;}
Możesz użyć tego kodu, aby wywołać metodę w taki sam sposób, jak kod przykładowy.
OJ, masz błąd składniowy . Statyczne słowo kluczowe powinno być używane tylko w definicji klasy, a nie w definicji metody.
andrewrk
90
Aby wyjaśnić swój zamiar w tym podejściu, możesz dodatkowo użyć prywatnego konstruktora. private: BitParser() {}Uniemożliwi to każdemu tworzenie instancji.
Danvil
7
Bezpieczeństwo wątku @MoatazElmasry stanowi problem podczas udostępniania stanu. W powyższej implementacji nie ma współdzielonego stanu, więc nie może być żadnych problemów z bezpieczeństwem wątków ... chyba że jesteś wystarczająco głupi, aby używać statyki wewnątrz tych funkcji. Więc tak, powyższy kod jest bezpieczny dla wątków, po prostu utrzymuj trwały stan z dala od swoich funkcji i jesteś dobry.
Dz.U.
@MoatazElmasry Incorrect. Dwa wątki nie mogą modyfikować niestatycznych zmiennych lokalnych w funkcji statycznej.
Dz.U.
12
Jeśli C ++ 11, argumentowałbym, że lepiej BitParser() = delete;odpowiednio przekazać zamiar usunięcia konstruktora (nie tylko ukrywanie go jako private).
Musisz jednak pamiętać, że „klasy statyczne” to włamania w językach podobnych do Javy (np. C #), które nie mogą mieć funkcji nie będących członkami, więc zamiast tego muszą przenieść je do klas jako metody statyczne.
W C ++ tak naprawdę chcesz funkcji nieosobistej, którą zadeklarujesz w przestrzeni nazw:
W C ++ przestrzeń nazw ma większą moc niż klasy dla wzorca „Java static method”, ponieważ:
metody statyczne mają dostęp do klas prywatnych symboli
prywatne metody statyczne są nadal widoczne (jeśli niedostępne) dla wszystkich, co nieco narusza enkapsulację
metody statyczne nie mogą być deklarowane w przód
metody statyczne nie mogą być przeciążone przez użytkownika klasy bez modyfikacji nagłówka biblioteki
nic nie da się zrobić za pomocą metody statycznej, której nie da się zrobić lepiej niż funkcja nie będąca członkiem (prawdopodobnie przyjacielem) w tej samej przestrzeni nazw
przestrzenie nazw mają własną semantykę (można je łączyć, mogą być anonimowe itp.)
itp.
Wniosek: Nie kopiuj / wklej tego wzorca Java / C # w C ++. W Javie / C # wzorzec jest obowiązkowy. Ale w C ++ jest to zły styl.
Edytuj 2010-06-10
Argumentowano za metodą statyczną, ponieważ czasami trzeba użyć statycznej zmiennej członka prywatnego.
Po pierwsze, myGlobal nazywa się myGlobal, ponieważ wciąż jest globalną zmienną prywatną. Spojrzenie na źródło CPP wyjaśni, że:
// CPP
std::string Foo::myGlobal ;// You MUST declare it in a CPPvoidFoo::barA(){// I can access Foo::myGlobal}voidFoo::barB(){// I can access Foo::myGlobal, too}void barC(){// I CAN'T access Foo::myGlobal !!!}
Na pierwszy rzut oka fakt, że bezpłatna funkcja barC nie może uzyskać dostępu do Foo :: myGlobal, wydaje się dobrą rzeczą z punktu widzenia enkapsulacji ... Fajnie, ponieważ ktoś patrząc na HPP nie będzie w stanie (chyba, że ucieknie się do sabotażu) uzyskać dostęp Foo :: myGlobal.
Ale jeśli przyjrzysz się temu uważnie, okaże się, że jest to kolosalny błąd: nie tylko twoja prywatna zmienna musi być nadal zadeklarowana w HPP (a więc widoczna dla całego świata, mimo że jest prywatna), ale musisz zadeklarować w tym samym HPP wszystkie (jak we WSZYSTKICH) funkcjach, które będą uprawnione do dostępu do niego !!!
Zatem używanie prywatnego statycznego członka jest jak chodzenie nago na zewnątrz z listą kochanków wytatuowaną na skórze: Nikt nie jest upoważniony do dotykania, ale każdy jest w stanie zerknąć. I bonus: każdy może mieć nazwiska osób upoważnionych do korzystania z twoich uprawnień.
private rzeczywiście ... :-D
Rozwiązanie „Anonimowe przestrzenie nazw”
Anonimowe przestrzenie nazw będą miały tę zaletę, że uczynią rzeczy prywatnymi naprawdę prywatnymi.
Najpierw nagłówek HPP
// HPPnamespaceFoo{void barA();}
Dla pewności, że zauważyłeś: Nie ma bezużytecznej deklaracji barB ani myGlobal. Co oznacza, że nikt nie czytający nagłówka nie wie, co kryje się za paskiem A.
Następnie CPP:
// CPPnamespaceFoo{namespace{
std::string myGlobal ;voidFoo::barB(){// I can access Foo::myGlobal}}void barA(){// I can access myGlobal, too}}void barC(){// I STILL CAN'T access myGlobal !!!}
Jak widać, podobnie jak tak zwana deklaracja „klasy statycznej”, fooA i fooB nadal mają dostęp do myGlobal. Ale nikt inny nie może. I nikt poza CPP nie wie, że fooB i myGlobal nawet istnieją!
W przeciwieństwie do „klasy statycznej” chodzącej nago z książką adresową wytatuowaną na skórze, „anonimowa” przestrzeń nazw jest w pełni ubrana , co wydaje się znacznie lepiej zamknięte AFAIK.
Czy to naprawdę ma znaczenie?
O ile użytkownicy Twojego kodu nie są sabotażystami (pozwolę ci, jako ćwiczenie, dowiedzieć się, jak można uzyskać dostęp do prywatnej części klasy publicznej za pomocą brudnego, niezdefiniowanego zachowania hack ...), co to privatejest private, nawet jeśli to jest widoczny w privatesekcji klasy zadeklarowanej w nagłówku.
Jeśli jednak chcesz dodać kolejną „funkcję prywatną” z dostępem do prywatnego członka, nadal musisz ją zadeklarować na całym świecie, modyfikując nagłówek, co jest moim zdaniem paradoksem: jeśli zmienię implementację mój kod (część CPP), a następnie interfejs (część HPP) NIE powinien się zmienić. Cytując Leonidasa: „ To jest ENCAPSULATION! ”
Edytuj 2014-09-20
Kiedy klasy metody statyczne są w rzeczywistości lepsze niż przestrzenie nazw z funkcjami nieczłonkowskimi?
Gdy musisz zgrupować funkcje i nakarmić tę grupę szablonem:
namespace alpha
{void foo();void bar();}structBeta{staticvoid foo();staticvoid bar();};template<typename T>structGamma{void foobar(){
T::foo();
T::bar();}};Gamma<alpha> ga ;// compilation errorGamma<Beta> gb ;// ok
gb.foobar();// ok !!!
Ponieważ jeśli klasa może być parametrem szablonu, przestrzenie nazw nie mogą.
GCC obsługuje -fno-access-control, którego można użyć w testach jednostek whitebox, aby uzyskać dostęp do członków klasy prywatnej. To jest jedyny powód, dla którego mogę wymyślić użycie członka klasy zamiast anonimowego / statycznego globalnego w implementacji.
@Tom: w każdym razie, IMHO, nawet biorąc pod uwagę testy jednostkowe, wady „pokazywania zbyt wielu rzeczy” przeważają nad zaletami. Wydaje mi się, że alternatywnym rozwiązaniem byłoby umieszczenie kodu do przetestowania w funkcji przyjmującej potrzebne parametry (i nie więcej) w utilitiesprzestrzeni nazw. W ten sposób, ta funkcja może być jednostka sprawdzone i nadal nie mają specjalnego dostępu do członków prywatnych (jak są one podane jako parametry w wywołaniu funkcji) ...
paercebal
@paercebal Mam zamiar wskoczyć na pokład twojego statku, ale mam jedną ostatnią rezerwację. Jeśli ktoś wskoczy w twoją namespacewolę, nie uzyska dostępu do twoich global, choć ukrytych, członków? Oczywiście musieliby zgadywać, ale jeśli celowo nie zaciemniacie swojego kodu, nazwy zmiennych są dość łatwe do odgadnięcia.
Zak.
@Zak: Owszem, mogli, ale tylko próbując to zrobić w pliku CPP, w którym deklarowana jest zmienna myGlobal. Chodzi o lepszą widoczność niż dostępność. W klasie statycznej zmienna myGlobal jest prywatna, ale nadal widoczna. Nie jest to tak ważne, jak się wydaje, ale mimo to w bibliotece DLL pokazanie symbolu, który powinien być prywatny dla biblioteki DLL w eksportowanym nagłówku, może być niezręczne ... W przestrzeni nazw myGlobal istnieje tylko w pliku CPP (ty może nawet pójść dalej i uczynić go statycznym). Ta zmienna nie pojawia się w nagłówkach publicznych.
paercebal,
63
Możesz także utworzyć bezpłatną funkcję w przestrzeni nazw:
W niektórych przypadkach możesz chcieć mieć enkapsulację danych, nawet jeśli klasa jest w większości „statyczna”. Dadzą ci to statyczni członkowie klasy prywatnej. Członkowie przestrzeni nazw są zawsze publiczni i nie mogą zapewniać hermetyzacji danych.
Torleif,
Jeśli zmienna „członek” jest deklarowana i dostępna tylko z pliku .cpp, jest bardziej prywatna niż zmienna prywatna zadeklarowana w pliku .h. NIE, że polecam tę technikę.
jmucchiello
3
@ Torleif: Mylisz się. przestrzenie nazw są lepsze do enkapsulacji niż statyczne prywatne elementy. Zobacz moją odpowiedź na demonstrację.
paercebal,
1
tak, ale w przestrzeni nazw należy zachować kolejność funkcji, w przeciwieństwie do klas z elementami statycznymi, na przykład void a () {b ();} b () {} spowoduje błąd w przestrzeni nazw, ale nie w klasie z członkowie statyczni
Moataz Elmasry
13
Jeśli szukasz sposobu zastosowania słowa kluczowego „static” do klasy, na przykład w języku C #
klasy statyczne są po prostu kompilatorem, który trzyma cię za rękę i powstrzymuje cię przed pisaniem metod / zmiennych instancji.
Jeśli po prostu napiszesz normalną klasę bez żadnych metod / zmiennych instancji, to jest to samo i tak właśnie zrobiłbyś w C ++
Nie narzekać (szczególnie na ciebie), ale staticdobrze byłoby trochę trzymać kompilatora za rękę, aby powstrzymać mnie od pisania lub wycinania / wklejania słowa 200 razy.
3Dave
Zgoda - ale klasa statyczna w C # też tego nie robi. Po prostu nie kompiluje się, gdy zapomnisz wkleić tam statyczny :-)
Orion Edwards
Tak - w porządku. Moje makra są wyświetlane. Szczerze mówiąc, jeśli zadeklaruję klasę jako statyczną, kompilator powinien zgłosić błąd tylko wtedy, gdy spróbuję go utworzyć. Reguły, które wymagają ode mnie powtarzania się, są wstrętne i powinny stać się pierwszym, gdy nadejdzie rewolucja.
3Dave
11
W C ++ chcesz utworzyć funkcję statyczną klasy (nie klasę statyczną).
Zmiana: W C ++ specyfikatory statyczne lub zewnętrzne mogą być stosowane tylko do nazw obiektów lub funkcji. Używanie tych specyfikatorów z deklaracjami typów jest nielegalne w C ++. W C te specyfikatory są ignorowane, gdy są używane w deklaracjach typu. Przykład:
staticstruct S {// valid C, invalid in C++int i;};
Uzasadnienie: Specyfikatory klas pamięci nie mają żadnego znaczenia, gdy są powiązane z typem. W C ++ członkowie klasy mogą być deklarowani za pomocą statycznego specyfikatora klasy pamięci. Dopuszczenie specyfikatorów klas pamięci w deklaracjach typu może sprawić, że kod będzie mylący dla użytkowników.
I jak struct, classjest także deklaracja typu.
To samo można wywnioskować, spacerując po drzewie składni w załączniku A.
Jak zauważono tutaj, lepszym sposobem na osiągnięcie tego w C ++ może być użycie przestrzeni nazw. Ale ponieważ nikt nie wspomniał finaltutaj o tym słowie kluczowym, piszę, static classjak mógłby wyglądać bezpośredni odpowiednik z C # w C ++ 11 lub nowszym:
classBitParser final
{public:BitParser()=delete;staticboolGetBitAt(int buffer,int pos);};boolBitParser::GetBitAt(int buffer,int pos){// your code}
Możesz „mieć” klasę statyczną w C ++, jak wspomniano wcześniej, klasa statyczna to taka, która nie ma żadnych instancji jej obiektów. W C ++ można to uzyskać, deklarując konstruktor / destruktor jako prywatny. Wynik końcowy jest taki sam.
Jest to podobne do sposobu, w jaki C # robi to w C ++
W pliku C #.cs możesz mieć prywatną zmienną wewnątrz funkcji publicznej. Znajdując się w innym pliku, możesz go użyć, wywołując przestrzeń nazw z funkcją jak w:
//Init the data (Link error if not done)intTheDataToBeHidden::_var1 =0;intTheDataToBeHidden::_var2 =0;//Implement the namespacenamespaceSharedData{voidSetError(constchar*Message,constchar*Title){//blah using TheDataToBeHidden::_var1, etc}voidDisplayError(void){//blah}}
OtherFile.h
#include"SharedModule.h"
OtherFile.cpp
//Call the functions using the hidden variablesSharedData::SetError("Hello","World");SharedData::DisplayError();
Ale wszyscy mogą przejść do TheDataToBeHidden -> To nie jest rozwiązanie
Guy L
3
W przeciwieństwie do innych zarządzanych języków programowania, „klasa statyczna” nie ma znaczenia w C ++. Możesz skorzystać ze statycznej funkcji członka.
Jednym z przypadków, w których przestrzenie nazw mogą nie być tak przydatne do osiągnięcia „klas statycznych”, jest użycie tych klas do uzyskania kompozycji zamiast dziedziczenia. Przestrzenie nazw nie mogą być przyjaciółmi klas, a zatem nie mogą uzyskać dostępu do prywatnych członków klasy.
Jedną (z wielu) alternatywą, ale najbardziej (moim zdaniem) eleganckim (w porównaniu do używania przestrzeni nazw i prywatnych konstruktorów do emulacji statycznego zachowania) sposobem na osiągnięcie „klasy, której nie można utworzyć” w C ++ byłoby zadeklarować funkcję czysto wirtualną za pomocą privatemodyfikatora dostępu.
Jeśli używasz C ++ 11, możesz zrobić wszystko, aby upewnić się, że klasa nie jest dziedziczona (w celu czystej emulacji zachowania klasy statycznej), używając finalspecyfikatora w deklaracji klasy, aby ograniczyć inne klasy przed dziedziczeniem .
// C++11 ONLYclassFoo final {public:staticint someMethod(int someArg);private:virtualvoid __dummy()=0;};
Choć może to zabrzmieć głupio i nielogicznie, C ++ 11 dopuszcza deklarację „funkcji wirtualnej, której nie można zastąpić”, której można użyć obok zadeklarowania klasy finalczysto i w pełni zaimplementować zachowanie statyczne, ponieważ powoduje to powstanie wyniku klasy, aby nie była dziedziczona, a funkcja manekina nie powinna być w żaden sposób nadpisywana.
// C++11 ONLYclassFoo final {public:staticint someMethod(int someArg);private:// Other private declarationsvirtualvoid __dummy()=0 final;};// Foo now exhibits all the properties of a static class
Odpowiedzi:
Jeśli szukasz sposobu zastosowania słowa kluczowego „static” do klasy, jak na przykład w C #, nie będziesz w stanie tego zrobić bez użycia Managed C ++.
Ale wygląd próbki wystarczy utworzyć publiczną metodę statyczną na obiekcie BitParser. Tak jak:
BitParser.h
BitParser.cpp
Możesz użyć tego kodu, aby wywołać metodę w taki sam sposób, jak kod przykładowy.
Mam nadzieję, że to pomaga! Twoje zdrowie.
źródło
private: BitParser() {}
Uniemożliwi to każdemu tworzenie instancji.BitParser() = delete;
odpowiednio przekazać zamiar usunięcia konstruktora (nie tylko ukrywanie go jakoprivate
).Zastanów się nad rozwiązaniem Matta Price'a .
To, czego chcesz, to wyrażone w semantyce C ++, aby umieścić swoją funkcję (ponieważ jest to funkcja) w przestrzeni nazw.
Edytuj 11.11.2011
W C ++ nie ma „klasy statycznej”. Najbliższą koncepcją byłaby klasa posiadająca wyłącznie metody statyczne. Na przykład:
Musisz jednak pamiętać, że „klasy statyczne” to włamania w językach podobnych do Javy (np. C #), które nie mogą mieć funkcji nie będących członkami, więc zamiast tego muszą przenieść je do klas jako metody statyczne.
W C ++ tak naprawdę chcesz funkcji nieosobistej, którą zadeklarujesz w przestrzeni nazw:
Dlaczego?
W C ++ przestrzeń nazw ma większą moc niż klasy dla wzorca „Java static method”, ponieważ:
Wniosek: Nie kopiuj / wklej tego wzorca Java / C # w C ++. W Javie / C # wzorzec jest obowiązkowy. Ale w C ++ jest to zły styl.
Edytuj 2010-06-10
Argumentowano za metodą statyczną, ponieważ czasami trzeba użyć statycznej zmiennej członka prywatnego.
Nie zgadzam się, jak pokazano poniżej:
Rozwiązanie „Statyczny członek prywatny”
Po pierwsze, myGlobal nazywa się myGlobal, ponieważ wciąż jest globalną zmienną prywatną. Spojrzenie na źródło CPP wyjaśni, że:
Na pierwszy rzut oka fakt, że bezpłatna funkcja barC nie może uzyskać dostępu do Foo :: myGlobal, wydaje się dobrą rzeczą z punktu widzenia enkapsulacji ... Fajnie, ponieważ ktoś patrząc na HPP nie będzie w stanie (chyba, że ucieknie się do sabotażu) uzyskać dostęp Foo :: myGlobal.
Ale jeśli przyjrzysz się temu uważnie, okaże się, że jest to kolosalny błąd: nie tylko twoja prywatna zmienna musi być nadal zadeklarowana w HPP (a więc widoczna dla całego świata, mimo że jest prywatna), ale musisz zadeklarować w tym samym HPP wszystkie (jak we WSZYSTKICH) funkcjach, które będą uprawnione do dostępu do niego !!!
Zatem używanie prywatnego statycznego członka jest jak chodzenie nago na zewnątrz z listą kochanków wytatuowaną na skórze: Nikt nie jest upoważniony do dotykania, ale każdy jest w stanie zerknąć. I bonus: każdy może mieć nazwiska osób upoważnionych do korzystania z twoich uprawnień.
private
rzeczywiście ... :-DRozwiązanie „Anonimowe przestrzenie nazw”
Anonimowe przestrzenie nazw będą miały tę zaletę, że uczynią rzeczy prywatnymi naprawdę prywatnymi.
Najpierw nagłówek HPP
Dla pewności, że zauważyłeś: Nie ma bezużytecznej deklaracji barB ani myGlobal. Co oznacza, że nikt nie czytający nagłówka nie wie, co kryje się za paskiem A.
Następnie CPP:
Jak widać, podobnie jak tak zwana deklaracja „klasy statycznej”, fooA i fooB nadal mają dostęp do myGlobal. Ale nikt inny nie może. I nikt poza CPP nie wie, że fooB i myGlobal nawet istnieją!
W przeciwieństwie do „klasy statycznej” chodzącej nago z książką adresową wytatuowaną na skórze, „anonimowa” przestrzeń nazw jest w pełni ubrana , co wydaje się znacznie lepiej zamknięte AFAIK.
Czy to naprawdę ma znaczenie?
O ile użytkownicy Twojego kodu nie są sabotażystami (pozwolę ci, jako ćwiczenie, dowiedzieć się, jak można uzyskać dostęp do prywatnej części klasy publicznej za pomocą brudnego, niezdefiniowanego zachowania hack ...), co to
private
jestprivate
, nawet jeśli to jest widoczny wprivate
sekcji klasy zadeklarowanej w nagłówku.Jeśli jednak chcesz dodać kolejną „funkcję prywatną” z dostępem do prywatnego członka, nadal musisz ją zadeklarować na całym świecie, modyfikując nagłówek, co jest moim zdaniem paradoksem: jeśli zmienię implementację mój kod (część CPP), a następnie interfejs (część HPP) NIE powinien się zmienić. Cytując Leonidasa: „ To jest ENCAPSULATION! ”
Edytuj 2014-09-20
Kiedy klasy metody statyczne są w rzeczywistości lepsze niż przestrzenie nazw z funkcjami nieczłonkowskimi?
Gdy musisz zgrupować funkcje i nakarmić tę grupę szablonem:
Ponieważ jeśli klasa może być parametrem szablonu, przestrzenie nazw nie mogą.
źródło
#define private public
w nagłówkach ... ^ _ ^ ...utilities
przestrzeni nazw. W ten sposób, ta funkcja może być jednostka sprawdzone i nadal nie mają specjalnego dostępu do członków prywatnych (jak są one podane jako parametry w wywołaniu funkcji) ...namespace
wolę, nie uzyska dostępu do twoichglobal
, choć ukrytych, członków? Oczywiście musieliby zgadywać, ale jeśli celowo nie zaciemniacie swojego kodu, nazwy zmiennych są dość łatwe do odgadnięcia.Możesz także utworzyć bezpłatną funkcję w przestrzeni nazw:
W BitParser.h
W BitParser.cpp
Zasadniczo byłby to preferowany sposób pisania kodu. Gdy obiekt nie jest potrzebny, nie używaj klasy.
źródło
klasy statyczne są po prostu kompilatorem, który trzyma cię za rękę i powstrzymuje cię przed pisaniem metod / zmiennych instancji.
Jeśli po prostu napiszesz normalną klasę bez żadnych metod / zmiennych instancji, to jest to samo i tak właśnie zrobiłbyś w C ++
źródło
static
dobrze byłoby trochę trzymać kompilatora za rękę, aby powstrzymać mnie od pisania lub wycinania / wklejania słowa 200 razy.W C ++ chcesz utworzyć funkcję statyczną klasy (nie klasę statyczną).
Powinieneś być w stanie wywołać funkcję przy użyciu BitParser :: getBitAt () bez tworzenia obiektu, który, jak zakładam, jest pożądanym rezultatem.
źródło
Czy mogę napisać coś takiego
static class
?Nie , zgodnie ze standardowym projektem C ++ 11 N3337, załącznik C 7.1.1:
I jak
struct
,class
jest także deklaracja typu.To samo można wywnioskować, spacerując po drzewie składni w załączniku A.
Warto zauważyć, że
static struct
było to legalne w C, ale nie miało żadnego skutku: dlaczego i kiedy używać struktur statycznych w programowaniu w C?źródło
Jak zauważono tutaj, lepszym sposobem na osiągnięcie tego w C ++ może być użycie przestrzeni nazw. Ale ponieważ nikt nie wspomniał
final
tutaj o tym słowie kluczowym, piszę,static class
jak mógłby wyglądać bezpośredni odpowiednik z C # w C ++ 11 lub nowszym:źródło
Możesz „mieć” klasę statyczną w C ++, jak wspomniano wcześniej, klasa statyczna to taka, która nie ma żadnych instancji jej obiektów. W C ++ można to uzyskać, deklarując konstruktor / destruktor jako prywatny. Wynik końcowy jest taki sam.
źródło
W Managed C ++ składnia klasy statycznej to: -
... lepiej późno niż wcale...
źródło
Jest to podobne do sposobu, w jaki C # robi to w C ++
W pliku C #.cs możesz mieć prywatną zmienną wewnątrz funkcji publicznej. Znajdując się w innym pliku, możesz go użyć, wywołując przestrzeń nazw z funkcją jak w:
Oto jak naśladować to samo w C ++:
SharedModule.h
SharedModule.cpp
OtherFile.h
OtherFile.cpp
źródło
W przeciwieństwie do innych zarządzanych języków programowania, „klasa statyczna” nie ma znaczenia w C ++. Możesz skorzystać ze statycznej funkcji członka.
źródło
Jednym z przypadków, w których przestrzenie nazw mogą nie być tak przydatne do osiągnięcia „klas statycznych”, jest użycie tych klas do uzyskania kompozycji zamiast dziedziczenia. Przestrzenie nazw nie mogą być przyjaciółmi klas, a zatem nie mogą uzyskać dostępu do prywatnych członków klasy.
źródło
Jedną (z wielu) alternatywą, ale najbardziej (moim zdaniem) eleganckim (w porównaniu do używania przestrzeni nazw i prywatnych konstruktorów do emulacji statycznego zachowania) sposobem na osiągnięcie „klasy, której nie można utworzyć” w C ++ byłoby zadeklarować funkcję czysto wirtualną za pomocą
private
modyfikatora dostępu.Jeśli używasz C ++ 11, możesz zrobić wszystko, aby upewnić się, że klasa nie jest dziedziczona (w celu czystej emulacji zachowania klasy statycznej), używając
final
specyfikatora w deklaracji klasy, aby ograniczyć inne klasy przed dziedziczeniem .Choć może to zabrzmieć głupio i nielogicznie, C ++ 11 dopuszcza deklarację „funkcji wirtualnej, której nie można zastąpić”, której można użyć obok zadeklarowania klasy
final
czysto i w pełni zaimplementować zachowanie statyczne, ponieważ powoduje to powstanie wyniku klasy, aby nie była dziedziczona, a funkcja manekina nie powinna być w żaden sposób nadpisywana.źródło