Menu
Coddy logo textTech

Elementy instancji a elementy statyczne

Część sekcji Programowanie obiektowe ścieżki C++ w Coddy. Lekcja 27 z 104.

Do tej pory każda utworzona przez Ciebie zmienna składowa należała do konkretnego obiektu. Gdy tworzysz dwa obiekty Player, każdy ma własne name i health. Nazywamy je składowymi instancji — istnieją osobno dla każdej instancji klasy.

A co, jeśli potrzebujesz danych współdzielonych przez wszystkie obiekty? Na przykład śledzenia łącznej liczby graczy.

W tym miejscu przydają się składowe statyczne. Składowa statyczna należy do samej klasy, a nie do żadnego konkretnego obiektu.

class Player {
    std::string name;           // Pole instancji – każdy gracz ma własne
    int health;                 // Pole instancji
    
    static int playerCount;     // Pole statyczne – wspólne dla WSZYSTKICH graczy
    
public:
    Player(std::string n) : name(n), health(100) {
        playerCount++;          // Zwiększ, gdy zostanie utworzony dowolny gracz
    }
    
    ~Player() {
        playerCount--;          // Zmniejsz, gdy zostanie zniszczony dowolny gracz
    }
};

Kluczowa różnica: składowe instancji są dostępne za pośrednictwem obiektu, natomiast do składowych statycznych można uzyskać dostęp za pomocą samej nazwy klasy. Pomyśl o składowych instancji jako o „jednej na obiekt”, a o składowych statycznych jako o „jednej na klasę”.

Składowe instancjiSkładowe statyczne
Unikalne dla każdego obiektuWspółdzielone przez wszystkie obiekty
Tworzone podczas tworzenia obiektuIstnieją, zanim zostanie utworzony jakikolwiek obiekt
Dostępne przez obiekt: player.healthDostępne przez klasę: Player::playerCount

Elementy statyczne są przydatne w przypadku liczników, wartości konfiguracyjnych lub wszelkich danych, które logicznie należą do klasy, a nie do poszczególnych obiektów.

challenge icon

Wyzwanie

Łatwy

Stwórzmy system ewidencji produktów, który śledzi zarówno szczegóły poszczególnych produktów, jak i ogólne statystyki zapasów, używając składowych instancji i statycznych.

Utworzysz dwa pliki, aby uporządkować swój kod:

  • Product.h: Zdefiniuj klasę Product, która zarządza poszczególnymi produktami, a także śledzi dane dotyczące całego stanu zapasów. Twoja klasa powinna zawierać:
    • Składowe instancji: name (string) i price (double): unikalne dla każdego produktu
    • Składową statyczną totalProducts, która zlicza, ile produktów aktualnie istnieje
    • Składową statyczną totalValue, która śledzi łączną cenę wszystkich produktów
    • Konstruktor, który przyjmuje nazwę i cenę, inicjalizuje składowe instancji oraz aktualizuje oba liczniki statyczne (zwiększa liczbę, dodaje cenę do łącznej wartości)
    • Destruktor, który aktualizuje liczniki statyczne po usunięciu produktu (zmniejsza liczbę, odejmuje cenę od łącznej wartości)
    • Metodę getInfo(), która zwraca ciąg znaków w formacie: "<name>: $<price>"
    • Metodę statyczną getInventoryStats(), która zwraca ciąg znaków: "Products: <count>, Total Value: $<value>"
  • main.cpp: Pokaż, jak składowe statyczne są współdzielone przez wszystkie obiekty, podczas gdy składowe instancji pozostają unikalne. Wczytaj z wejścia nazwy dwóch produktów i ich ceny (name1, price1, name2, price2: każda wartość w osobnym wierszu), a następnie:
    • Wyświetl początkowe statystyki zapasów, używając nazwy klasy: Product::getInventoryStats()
    • Utwórz blok zakresu z nawiasami klamrowymi, a w nim utwórz obiekt Product z pierwszą nazwą i ceną. Wyświetl jego informacje i bieżące statystyki zapasów.
    • Po zakończeniu bloku (zniszczeniu pierwszego produktu) wyświetl "After first scope:", a następnie statystyki zapasów
    • Utwórz kolejny obiekt Product z drugą nazwą i ceną. Wyświetl jego informacje i statystyki zapasów.
    • Utwórz trzeci obiekt Product o nazwie "Bonus" i cenie 5.00. Wyświetl końcowe statystyki zapasów.

Pamiętaj, aby zdefiniować składowe statyczne poza klasą w pliku nagłówkowym (po definicji klasy). Formatuj ceny, używając dwóch miejsc po przecinku za pomocą std::fixed i std::setprecision(2) z <iomanip>.

Dołącz plik nagłówkowy w main.cpp, używając #include "Product.h".

Spróbuj swoich sił

#include <iostream>
#include <string>
#include "Product.h"

using namespace std;

int main() {
    // Wczytaj dane wejściowe
    string name1;
    double price1;
    string name2;
    double price2;
    
    getline(cin, name1);
    cin >> price1;
    cin.ignore();
    getline(cin, name2);
    cin >> price2;
    
    // TODO: Wyświetl początkowe statystyki stanu magazynowego, używając Product::getInventoryStats()
    
    // TODO: Utwórz blok o zasięgu ograniczonym nawiasami klamrowymi
    // Wewnątrz bloku:
    //   - Utwórz obiekt Product z name1 i price1
    //   - Wyświetl informacje o nim, używając getInfo()
    //   - Wyświetl bieżące statystyki stanu magazynowego
    
    // TODO: Po zakończeniu bloku wyświetl "After first scope:"
    // Następnie wyświetl statystyki stanu magazynowego
    
    // TODO: Utwórz kolejny obiekt Product z name2 i price2
    // Wyświetl informacje o nim oraz statystyki stanu magazynowego
    
    // TODO: Utwórz trzeci obiekt Product o nazwie "Bonus" i cenie 5.00
    // Wypisz końcowe statystyki stanu magazynowego
    
    return 0;
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C++ online