Struktura a klasa
Część sekcji Programowanie obiektowe ścieżki C++ w Coddy. Lekcja 37 z 104.
W C++ struct i class są niemal identyczne. Oba mogą mieć zmienne składowe, funkcje składowe, konstruktory i obsługiwać dziedziczenie. Jedyną różnicą jest ich domyślny poziom dostępu.
W class składowe są domyślnie prywatne. W struct składowe są domyślnie publiczne:
struct Point {
int x; // domyślnie publiczne
int y; // domyślnie publiczne
};
class Circle {
double radius; // domyślnie prywatne
public:
double getRadius() { return radius; }
};Dotyczy to również dziedziczenia. Struktura dziedziczy domyślnie publicznie, a klasa — prywatnie:
struct DerivedStruct : Base {}; // dziedziczenie publiczne
class DerivedClass : Base {}; // dziedziczenie prywatnePoza tymi wartościami domyślnymi nie ma żadnej różnicy technicznej. Konwencja ma jednak znaczenie.
Większość programistów C++ używa struct do prostych kontenerów danych z publicznymi składowymi (takimi jak współrzędne lub konfiguracja), a class, gdy ważne są enkapsulacja i zachowanie. Stosowanie się do tej konwencji sprawia, że intencje Twojego kodu są jaśniejsze dla innych programistów.
Wyzwanie
ŁatwyZbudujmy prosty system konfiguracji, który pokazuje, kiedy zgodnie z konwencjami C++ używać struct, a kiedy class. Utworzysz struct dla prostych danych, które mają być publicznie dostępne, oraz class dla danych wymagających enkapsulacji i kontrolowanego dostępu.
Utworzysz dwa pliki, aby uporządkować kod:
Config.h: Zdefiniuj zarówno strukturę, jak i klasę reprezentujące różne rodzaje danych konfiguracyjnych.Najpierw utwórz
structo nazwieDimensions: prosty kontener danych przechowujący szerokość i wysokość (obie wartości typuint). Ponieważ składowe struktur są domyślnie publiczne, powinny być dostępne bezpośrednio, bez metod pobierających. Dodaj metodęarea(), która zwraca iloczyn szerokości i wysokości.Następnie utwórz
classo nazwieAppConfig, która zarządza ustawieniami aplikacji przy użyciu odpowiedniej enkapsulacji. Powinna przechowywać nazwę aplikacji (string) oraz obiektDimensionsokreślający rozmiar okna. Ponieważ składowe klas są domyślnie prywatne, musisz jawnie udostępnić publiczny interfejs. Zapewnij:- Konstruktor przyjmujący nazwę aplikacji, szerokość i wysokość
- Metodę pobierającą
getAppName(), która zwraca nazwę - Metodę pobierającą
getWindowSize(), która zwraca obiektDimensions - Metodę
displayConfig(), która wyświetla:"App: <name>, Window: <width>x<height>, Area: <area>"
main.cpp: Zademonstruj różnicę między użyciem struktury a klasy. Wczytaj nazwę aplikacji, szerokość i wysokość ze standardowego wejścia (z trzech osobnych wierszy), a następnie:- Utwórz strukturę
Dimensionsbezpośrednio z wartościami szerokości i wysokości; odwołaj się bezpośrednio do jej składowych, aby wyświetlić:"Direct struct access: <width> x <height>" - Utwórz obiekt
AppConfigze wszystkimi trzema wartościami - Wywołaj
displayConfig(), aby wyświetlić pełną konfigurację - Użyj metody pobierającej, aby pobrać wymiary okna i wyświetlić:
"Via getter - Area: <area>"
- Utwórz strukturę
To wyzwanie podkreśla konwencję: używaj struct, gdy masz proste, przejrzyste dane (takie jak współrzędne lub wymiary), a class, gdy chcesz kontrolować dostęp i dodawać zachowanie do danych.
Konwertuj wartości szerokości i wysokości wczytane jako ciągi znaków na liczby całkowite za pomocą std::stoi(). Nie zapomnij o strażnikach nagłówka w pliku nagłówkowym.
Spróbuj swoich sił
#include <iostream>
#include <string>
#include "Config.h"
using namespace std;
int main() {
// Wczytaj dane wejściowe
string appName;
string widthStr;
string heightStr;
getline(cin, appName);
getline(cin, widthStr);
getline(cin, heightStr);
int width = stoi(widthStr);
int height = stoi(heightStr);
// TODO: Utwórz strukturę Dimensions z polami width i height
// Uzyskaj bezpośredni dostęp do jej pól, aby wypisać: "Direct struct access: <width> x <height>"
// TODO: Utwórz obiekt AppConfig z wartościami appName, width i height
// TODO: Wywołaj displayConfig() na obiekcie AppConfig
// TODO: Użyj gettera getWindowSize(), aby uzyskać wymiary i wypisać: "Via getter - Area: <area>"
return 0;
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneBudowanie i kompilacja C++Pliki nagłówkowe i pliki źródłowePrzestrzenie nazw i zakresWprowadzenie do programowania obiektowego w C++Klasy a obiektyWskaźnik „this”Metody (funkcje składowe)Atrybuty (składowe danych)Podstawy konstruktorów i destruktorówPowtórzenie – prosty kalkulator4Właściwości klas
Elementy instancji a elementy statyczneGettery i setteryStałe funkcje składoweSłowo kluczowe mutableMetody i zmienne statyczneFunkcje i klasy zaprzyjaźnionePodsumowanie – menedżer konta bankowego7Dziedziczenie
Podstawy dziedziczeniaPoziomy dostępu w dziedziczeniuKolejność wywołań konstruktora i destruktoraNadpisywanie metodFunkcje wirtualne i VTableWielokrotne dziedziczenieDziedziczenie wirtualnePowtórzenie — hierarchia pracowników2Zarządzanie pamięcią
Pamięć stosu a stertyWskaźniki i referencjePamięć dynamiczna (new/delete)Inteligentne wskaźniki w C++RAII w C++Podsumowanie — menedżer tablicy dynamicznej5Hermetyzacja
Specyfikatory dostępu w C++Specyfikatory dostępu — szczegółowoUkrywanie informacjiStruktura a klasaKlasy zagnieżdżone i wewnętrznePodsumowanie — system ewidencji studentów8Polimorfizm
Polimorfizm czasu kompilacji i wykonaniaPrzeciążanie funkcjiFunkcje wirtualne — powtórkaCzysto wirtualne funkcjeKlasy abstrakcyjneProjektowanie interfejsów w C++Rzutowanie dynamiczne i RTTIPodsumowanie — kalkulator kształtów3Konstruktory i destruktory
Konstruktor domyślnyKonstruktor z parametramiKonstruktor kopiującyKonstruktor przenoszącyListy inicjalizacyjne konstruktoraKonstruktory delegująceDestruktor — szczegółowe omówienieZasada trzech / pięciu / zeraPodsumowanie — klasa String6Przeciążanie operatorów
Wprowadzenie do przeciążania operatorówPrzeciążanie operatorów arytmetycznychPrzeciążanie operatorów porównaniaOperatory strumieniowePrzeciążanie operatora przypisaniaPrzeciążanie operatorów [] i ()Operatory konwersji typówPodsumowanie — klasa Matrix9Szablony
Szablony funkcjiSzablony klasSpecjalizacja szablonówSzablony wariadycznePodstawy SFINAE i cech typówPodsumowanie — kontener generycznyPoćwicz samodzielnie: Kompilator C++ online