Ostatnia aktualizacja: 08.10.2017

Oprócz zmiennych i metod, które są bezpośrednio związane z obiektem, C++ umożliwia definiowanie zmiennych i metod, które są bezpośrednio związane z klasą lub w inny sposób. członkowie statyczni klasa. Zmienne i metody statyczne odnoszą się ogólnie do całej klasy. Do ich zdefiniowania używane jest słowo kluczowe static.

Na przykład bank może mieć wiele różnych depozytów, ale wszystkie depozyty będą miały pewne wspólne oprocentowanie. Tak więc, aby opisać konto bankowe, definiujemy i stosujemy następującą klasę:

#włączać class Account ( public: Account(double sum) ( this->sum = sum; ) static int getRate() ( return rate; ) static void setRate(int r) ( rate = r; ) double getIncome() ( return sum + suma * stawka / 100; ) prywatne: suma podwójna; statyczna stawka int; ); int Konto::stawka = 8; int main() ( Konto konto1(20000); Konto konto2(50000); Konto::setRate(5); // zresetuj stawkę std::cout<< "Rate: " << Account::getRate() << std::endl; std::cout << "Rate: " << account1.getRate() << " Income: " << account1.getIncome() << std::endl; std::cout << "Rate: " << account2.getRate() << " Income: " << account2.getIncome() << std::endl; return 0; }

Klasa Account definiuje jedną zmienną statyczną, stawkę i dwie statyczne funkcje do zarządzania tą zmienną. Przy definiowaniu funkcji statycznych należy pamiętać, że w ich wnętrzu możemy używać tylko statycznych zmiennych klas, takich jak zmienna szybkości. Zmienne niestatyczne nie mogą być używane w funkcjach statycznych.

Ponadto wskaźnik this nie może być stosowany w funkcjach statycznych, co jest w zasadzie oczywiste, ponieważ wskazuje na bieżący obiekt, a funkcje statyczne odnoszą się do całej klasy jako całości.

Ważne jest również to, że jeśli klasa zawiera zmienne statyczne, to muszą być dodatkowo zdefiniowane poza klasą:

Konto międzynarodowe::stawka = 8;

Nie jest konieczne przypisywanie zmiennej wartości początkowej.

Warto również zauważyć, że ponieważ elementy statyczne odnoszą się do całej klasy jako całości, elementy statyczne są określane przy użyciu nazwy klasy, po której następuje operator ::. Lub możemy również uzyskać dostęp do publicznych członków klasy poprzez zmienne tej klasy:

Konto::getRate() konto1.getRate()

Konsola wyjścia programu:

Stawka: 5 Stawka: 5 Dochód: 21000 Stawka: 5 Dochód: 52500

W klasach często stosuje się również stałe statyczne. Na przykład ustawmy zmienną stawkę jako stałą w klasie Konto:

#włączać class Konto ( public: const static int rate = 8; Account(podwójna suma) ( this->sum = suma; ) double getIncome() ( zwracana suma + suma * stawka / 100; ) private: podwójna suma; ); int main() ( Konto 1 (20000); Konto 2 (50000); std::cout<< "Rate: " << account1.rate << "\tIncome: " << account1.getIncome() << std::endl; std::cout << "Rate: " << account2.rate << "\tIncome: " << account2.getIncome() << std::endl; return 0; }

W przeciwieństwie do zmiennych statycznych, stałe statyczne nie muszą być dalej definiowane poza klasą.

Oprócz modyfikatora dostępu możesz wpisać słowo kluczowe przed nazwą pola, metody lub właściwości statyczny .
« statyczny " oznacza, że ​​dane pole, metoda lub właściwość nie będą należeć do każdego obiektu klasy, ale do wszystkich razem.

Klasyczny przykład: jak określić, ile obiektów tej samej klasy zostało utworzonych? Aby rozwiązać ten problem, po prostu podawaj pola i metody statyczne.

Spójrzmy na przykład tygrysów. Zdefiniujmy klasę „ Tygrys”. Jeśli napiszemy pole klasy w ten sposób: liczba publicznych int; wtedy każdy obiekt będzie miał to pole, a każdy obiekt będzie miał swoje własne. Co więcej, jeśli nie zostanie utworzony ani jeden obiekt, to pole w ogóle nie będzie istnieć.
Dlatego zróbmy to pole statyczne ( statyczny).

Stwórzmy konstruktor, w którym będziemy zwiększać licznik liczyć podczas tworzenia każdego nowego obiektu:
public Tiger() ( liczba++; ).
Tutaj możemy również ustawić indywidualne cechy tygrysa: wagę, wzrost, pseudonim.

Napiszemy również statyczną metodę wyświetlającą liczbę utworzonych obiektów:
public static void ShowNumberOfObjects().

Wtedy nasza aplikacja konsolowa będzie miała dwie klasy:

Public class Tiger ( public static int count; public Tiger() ( count++; ) public static void ShowNumberOfObjects() ( Console.WriteLine("Tygrysy = (0)", Tiger.count.ToString()); ) ) class Program ( static void Main(string args) ( // Jaka jest liczba tygrysów bez tworzenia obiektów? Tiger.ShowNumberOfObjects(); // 0 ponieważ nie utworzyliśmy jeszcze obiektów // Utwórz 3 tygrysy Tygrys t1 = nowy Tygrys (); Tygrys t2 = nowy Tygrys (); Tygrys t3 = nowy Tygrys (); Tygrys.ShowNumberOfObjects(); // 3 tygrysy wyjdą Console.ReadLine(); ) )

Wynik: 3.

Wniosek. Metoda statyczna umożliwia wywołanie jej bez posiadania dostępnego obiektu. Zamiast nazwy obiektu przy wywołaniu metody podawana jest nazwa klasy Tiger: Tiger.ShowNumberOfObjects();

Różnice między metodą statyczną a niestatyczną:

1. Nie potrzebujesz obiektu do wywołania metody statycznej.
2. Wewnątrz metody statycznej ta zmienna wskazująca obiekt jest niedostępna, w związku z tym wszystkie niestatyczne pola tej klasy nie są dostępne, ponieważ jak żaden przedmiot.
3. Wewnątrz normalnej metody dostępne są zarówno pola statyczne, jak i niestatyczne.
4. Począwszy od C# 4.0, możliwe stało się uczynienie samej klasy statyczną.

Czasami tworzysz klasy, które składają się tylko z metod statycznych, takich jak klasa Math. W rzeczywistości takie klasy są kontenerami funkcji globalnych, jednak odbiega to od koncepcji OOP. Nie będzie również możliwe tworzenie odpowiednio instancji klasy statycznej.

Zajmijmy się teraz pojęciem „struktury” i dowiedzmy się, jak różni się ona od klasy.

Ostatnia aktualizacja: 25.12.2018

Oprócz zwykłych pól, metod, właściwości, klasa może mieć statyczne pola, metody, właściwości. Pola statyczne, metody, właściwości odnoszą się do całej klasy i nie jest konieczne tworzenie instancji klasy, aby uzyskać dostęp do podobnych elementów klasy. Na przykład:

Class Konto ( public statyczna premia dziesiętna = 100; public dziesiętna suma sumy; public Account(suma dziesiętna) ( totalSum = suma + premia; ) ) class Program ( static void Main(string args) ( Console.WriteLine(Account.bonus); / / 100 Account.bonus += 200;Account account1 = new Account(150);Console.WriteLine(account1.totalSum); // 450 Account account2 = new Account(1000);Console.WriteLine(account2.totalSum); // 1300 Konsola.ReadKey(; ) )

W tym przypadku klasa Account posiada dwa pola: bonus i totalSum. Pole bonusowe jest statyczne, więc przechowuje stan klasy jako całości, a nie pojedynczego obiektu. I tak możemy odwoływać się do tego pola po nazwie klasy:

Konsola.WriteLine(Konto.bonus); Konto.bonus += 200;

Na poziomie pamięci dla pól statycznych zostanie utworzony obszar pamięci, który będzie wspólny dla wszystkich obiektów klasy.

Jednocześnie pamięć dla zmiennych statycznych jest alokowana nawet jeśli nie został utworzony żaden obiekt tej klasy.

Właściwości i metody statyczne

Podobnie możemy tworzyć i wykorzystywać statyczne metody i właściwości:

Konto klasy ( konto publiczne (suma dziesiętna, stawka dziesiętna) ( jeśli (suma< MinSum) throw new Exception("Недопустимая сумма!"); Sum = sum; Rate = rate; } private static decimal minSum = 100; // минимальная допустимая сумма для всех счетов public static decimal MinSum { get { return minSum; } set { if(value>0) minSuma = wartość; ) ) publiczny zestaw dziesiętny Suma ( get; zestaw prywatny; ) // kwota na rachunku publiczny zestaw dziesiętny Stopa ( get; zestaw prywatny; ) // oprocentowanie // wyliczenie kwoty na rachunku po określonym okresie po określonej stawce public statyczny dziesiętny GetSum(suma dziesiętna , współczynnik dziesiętny, okres int) ( wynik dziesiętny = suma; for (int i = 1; i<= period; i++) result = result + result * rate / 100; return result; } }

Zmienna minSum, właściwość MinSum i metoda GetSum są tutaj zdefiniowane za pomocą słowa kluczowego static, co oznacza, że ​​są statyczne.

Zmienna minSum i właściwość MinSum reprezentują minimalną kwotę dozwoloną na utworzenie faktury. Ten wskaźnik nie odnosi się do żadnego konkretnego rachunku, ale dotyczy wszystkich rachunków w ogóle. Jeśli zmienimy ten wskaźnik dla jednego konta, to musi on również zmienić się dla drugiego konta. Oznacza to, że w przeciwieństwie do właściwości Sum i Rate, które przechowują stan obiektu, zmienna minSum przechowuje stan dla wszystkich obiektów danej klasy.

To samo z metodą GetSum - oblicza kwotę na koncie po pewnym okresie przy określonym oprocentowaniu za określoną kwotę początkową. Wywołanie i wynik tej metody nie zależy od konkretnego obiektu ani jego stanu.

Dlatego zmienne i właściwości, które przechowują stan wspólny dla wszystkich obiektów klasy, powinny być zdefiniowane jako statyczne. A także metody definiujące zachowanie wspólne dla wszystkich obiektów również powinny być zadeklarowane jako statyczne.

Statyczne elementy klasy są wspólne dla wszystkich obiektów tej klasy, więc muszą być określane nazwą klasy:

Należy zauważyć, że metody statyczne mają dostęp tylko do statycznych członków klasy. Nie możemy odwoływać się do niestatycznych metod, pól, właściwości wewnątrz metody statycznej.

Często do przechowywania liczników używane są pola statyczne. Załóżmy na przykład, że mamy klasę User i chcemy mieć licznik, który mówi nam, ile obiektów User zostało utworzonych:

Class User ( private static int counter = 0; public User() ( counter++; ) public static void DisplayCounter() ( Console.WriteLine($"Utworzone (licznik) obiekty użytkownika"); ) ) class Program ( static void Main(string) args) ( Użytkownik użytk1 = nowy Użytkownik(); Użytkownik użytk2 = nowy Użytkownik(); Użytkownik użytk3 = nowy Użytkownik(); Użytkownik użytk4 = nowy Użytkownik(); Użytkownik użytk5 = nowy Użytkownik(); Użytkownik.WyświetlaczLicznik(); / / 5 Konsola.ReadKey(; ) )

Konstruktor statyczny

Oprócz zwykłych konstruktorów klasa może mieć również konstruktory statyczne. Konstruktory statyczne mają następujące cechy wyróżniające:

    Konstruktory statyczne nie mogą mieć modyfikatora dostępu i nie mogą przyjmować parametrów

    Podobnie jak w przypadku metod statycznych, konstruktory statyczne nie mogą używać słowa kluczowego this do odwoływania się do bieżącego obiektu klasy i mają dostęp tylko do statycznych elementów klasy

    Konstruktory statyczne nie mogą być wywoływane ręcznie w programie. Są one wykonywane automatycznie przy pierwszym tworzeniu obiektu tej klasy lub przy pierwszym dostępie do jego statycznych składowych (jeśli istnieją)

Konstruktory statyczne są zwykle używane do inicjowania danych statycznych lub wykonują akcje, które należy wykonać tylko raz.

Zdefiniujmy konstruktor statyczny:

Class User ( static User() ( Console.WriteLine("Pierwszy użytkownik został utworzony"); ) ) class Program ( static void Main(string args) ( User user1 = new User(); // tutaj będzie działał konstruktor statyczny User user2 = new User(); Console.Read(); ) )

Klasy statyczne

Klasy statyczne są deklarowane z modyfikatorem static i mogą zawierać tylko statyczne pola, właściwości i metody. Na przykład, jeśli klasa Account miała tylko statyczne zmienne, właściwości i metody, to mogłaby być zadeklarowana jako statyczna:

Klasa statyczna Konto ( private statyczna minSum dziesiętna = 100; // minimalna dopuszczalna kwota dla wszystkich kont public static dziesiętna minSum ( get ( return minSum; ) set ( if(value>0) minSum = value; ) ) // obliczenie konta kwota po pewnym okresie po określonym tempie public statyczny dziesiętny GetSum(suma dziesiętna, kurs dziesiętny, okres int) ( wynik dziesiętny = suma; for (int i = 1; i<= period; i++) result = result + result * rate / 100; return result; } }

W C# dobrym przykładem klasy statycznej jest klasa Math, która jest używana do różnych operacji matematycznych.

Lekcja 25

Do tej pory każdy tworzony obiekt ma swój własny zestaw elementów danych. W zależności od przeznaczenia aplikacji mogą wystąpić sytuacje, w których obiekty tej samej klasy muszą współużytkować jeden lub więcej elementów członkowskich danych. Załóżmy na przykład, że piszesz program płatności, który śledzi godziny pracy 1000 pracowników. Aby ustalić stawkę podatku, program musi znać warunki, w jakich pracuje każdy pracownik. Użyjmy do tego zmiennej klasy stan_pracy. Jeśli jednak wszyscy pracownicy pracują w tych samych warunkach, Twój program może udostępniać ten element danych dla wszystkich obiektów typu pracownik. Więc twój program zmniejsza wymaganą ilość pamięci, wyrzucając 999 kopii tych samych informacji. Aby udostępnić element klasy, musisz zadeklarować ten element jako statyczny (statyczny). Ta lekcja obejmuje kroki, które należy wykonać, aby udostępnić element klasy między wieloma obiektami. Pod koniec tej lekcji opanujesz następujące podstawowe pojęcia:

    C++ pozwala na posiadanie obiektów tego samego typu, które współdzielą jednego lub więcej członków klasy.

    Jeśli twój program przypisuje wartość do współdzielonego elementu, wszystkie obiekty tej klasy natychmiast uzyskują dostęp do tej nowej wartości.

    Aby utworzyć członka danych klasy współużytkowanej, musisz poprzedzić nazwę członka klasy słowem kluczowym statyczny.

    Po tym, jak program zadeklarował członka klasy jako statyczny, musi zadeklarować zmienną globalną (poza definicją klasy), która odpowiada temu współdzielonemu członkowi klasy.

    Twoje programy mogą używać słowa kluczowego statyczny, aby uczynić metodę klasy wywoływalną, podczas gdy program mógł jeszcze nie zadeklarować żadnych obiektów tej klasy.

UDOSTĘPNIONE ELEMENTY

Zazwyczaj podczas tworzenia obiektów określonej klasy każdy obiekt otrzymuje własny zestaw elementów członkowskich danych. Mogą jednak wystąpić sytuacje, w których obiekty tej samej klasy muszą współdzielić jeden lub więcej elementów danych. (statyczny e elementy danych). W takich przypadkach zadeklaruj członków danych jako: ogólny muł oraz prywatny, a następnie poprzedź typ słowem kluczowym statyczny, jak poniżej:

prywatne: statyczne int shared_value;

Po zadeklarowaniu klasy należy zadeklarować element jako zmienną globalną poza klasą, jak pokazano poniżej:

int nazwa_klasy::wartość_współdzielona;

Poniższy program SHARE_IT.CPP definiuje klasę seria książek, element współdzielenia Liczba stron, co jest takie samo dla wszystkich obiektów (książek) klasy (serii). Jeśli program zmieni wartość tego elementu, zmiana zostanie natychmiast odzwierciedlona we wszystkich obiektach klasy:

#włączać

#włączać

klasa_seria_książek

( public: book_series(char *, char *, float); void show_book(void); void set_pages(int) ; prywatne: statyczna int liczba_stron; tytuł znaku; autor znaku[64]; cena zmiennoprzecinkowa; );

int seria_książek::liczba_stron;

void book_series::set_pages(strony wewnętrzne)

( liczba_stron = strony; )

book_series::book_series(znak *tytuł, znak *autor, cena zmiennoprzecinkowa)

( strcpy(seria_książki::tytuł, tytuł); strcpy(seria_książki::autor, autor);seria_książki::cena = cena; )

void book_series::show_book(void)

(cout<< "Заголовок: " << title << endl; cout << "Автор: " << author << endl; cout << "Цена: " << price << endl; cout << "Страницы: " << page_count << endl; }

( book_series programowanie("Nauka programowania w C++", "Jamsa", 22.95); book_series word("Nauka używania programu Word dla Windows", "Wyatt", 19.95); word.set_pages(256); programowanie.show_book () ;słowo.show_book() ; cout<< endl << "Изменение page_count " << endl; programming.set_pages(512); programming.show_book(); word.show_book(); }

Jak widać klasa deklaruje Liczba stron Jak statyczny wewn. Zaraz po definicji klasy program deklaruje element Liczba stron jako zmienna globalna. Gdy program zmienia element Liczba stron, zmiana jest natychmiast odzwierciedlona we wszystkich obiektach klasy seria książek.

Udostępnianie członków klasy

W zależności od programu mogą wystąpić sytuacje, w których konieczne będzie współdzielenie pewnych danych między wieloma instancjami obiektu. Aby to zrobić, zadeklaruj taki element jako statyczny. Następnie zadeklaruj ten element poza klasą jako zmienną globalną. Wszelkie zmiany wprowadzone przez program w tym elemencie zostaną natychmiast odzwierciedlone w obiektach tej klasy.

Używanie elementów z atrybutamipubliczne statyczne, jeśli obiekty nie istnieją

Jak się właśnie dowiedziałeś, deklarując członka klasy jako statyczny ten element jest wspólny dla wszystkich obiektów danej klasy. Mogą jednak zaistnieć sytuacje, w których program nie utworzył jeszcze obiektu, ale musi użyć elementu. Aby użyć elementu, Twój program musi go zadeklarować jako publiczny oraz statyczny. Na przykład następujący program USE_MBR.CPP używa elementu Liczba stron z klasy seria książek, nawet jeśli obiekty tej klasy nie istnieją:

#włączać

#włączać

klasa_seria_książek

(publiczne: statyczne int liczba_stron; prywatne: tytuł znaku; autor znaku; cena zmiennoprzecinkowa; );

int seria_książek::ilość_stron;

void main(void) ( book_series::page_count = 256; cout<< "Текущее значение page_count равно " << book_series::page_count << endl; }

W tym przypadku, ponieważ klasa definiuje element klasy Liczba stron Jak publiczny, program może odwoływać się do tego elementu klasy, nawet jeśli obiekty klasy seria książek nie istnieje.

KORZYSTANIE Z FUNKCJI STATYCZNYCH CZŁONKÓW

Poprzedni program zilustrował zastosowanie statyczny elementy danych. Podobnie C++ pozwala zdefiniować statyczny funkcje składowe (metody). Jeśli tworzysz statyczny Twój program może wywołać tę metodę, nawet jeśli nie utworzono żadnych obiektów. Na przykład, jeśli klasa zawiera metodę, której można użyć na danych poza klasą, możesz zrobić tę metodę statyczny. Poniżej znajduje się klasa menu, który używa sekwencji esc sterownika ANSI do wyczyszczenia ekranu wyświetlacza. Jeśli masz zainstalowany sterownik ANSI.SYS w swoim systemie, możesz użyć metody czysty ekran aby wyczyścić ekran. Ponieważ ta metoda jest zadeklarowana jako statyczny, program może z niego korzystać, nawet jeśli obiekty typu menu nie istnieje. Poniższy program CLR_SCR.CPP używa metody czysty ekran aby wyczyścić ekran wyświetlacza:

#włączać

( public: static void clear_screen(void); // Inne metody powinny być tutaj prywatne: int number_of_menu_options; );

void menu::clear_screen(void)

(cout<< "\033" << "}