Struct vs class
Fa parte della sezione Programmazione orientata agli oggetti del percorso C++ di Coddy. Lezione 37 di 104.
In C++, struct e class sono quasi identici. Entrambi possono avere variabili membro, funzioni membro, costruttori e supportare l'ereditarietà. L'unica differenza è il loro livello di accesso predefinito.
In una class, i membri sono privati per impostazione predefinita. In una struct, i membri sono pubblici per impostazione predefinita:
struct Point {
int x; // pubblico per impostazione predefinita
int y; // pubblico per impostazione predefinita
};
class Circle {
double radius; // privato per impostazione predefinita
public:
double getRadius() { return radius; }
};Questo vale anche per l’ereditarietà. Una struct eredita pubblicamente per impostazione predefinita, mentre una class eredita privatamente:
struct DerivedStruct : Base {}; // ereditarietà pubblica
class DerivedClass : Base {}; // ereditarietà privataOltre a questi valori predefiniti, non c'è alcuna differenza tecnica. Tuttavia, le convenzioni sono importanti.
La maggior parte dei programmatori C++ usa struct per semplici contenitori di dati con membri pubblici (come una coordinata o una configurazione) e class quando l'incapsulamento e il comportamento sono importanti. Seguire questa convenzione rende più chiara l'intenzione del tuo codice agli altri sviluppatori.
Sfida
FacileCreiamo un semplice sistema di configurazione che mostra quando usare struct invece di class secondo le convenzioni del C++. Creerai una struct per dati semplici pensati per essere accessibili liberamente e una class per dati che richiedono incapsulamento e accesso controllato.
Creerai due file per organizzare il codice:
Config.h: definisci sia una struct sia una class che rappresentano diversi tipi di dati di configurazione.Per prima cosa, crea una
structchiamataDimensions: un semplice contenitore di dati per larghezza e altezza (entrambe di tipoint). Poiché i membri delle struct sono pubblici per impostazione predefinita, dovrebbero essere accessibili direttamente senza getter. Includi un metodoarea()che restituisce il prodotto della larghezza per l'altezza.Poi, crea una
classchiamataAppConfigche gestisce le impostazioni dell'applicazione con un incapsulamento appropriato. Dovrebbe memorizzare il nome di un'app (stringa) e un oggettoDimensionsper le dimensioni della finestra. Poiché i membri delle classi sono privati per impostazione predefinita, dovrai rendere esplicitamente accessibile l'interfaccia pubblica. Fornisci:- Un costruttore che accetta il nome dell'app, la larghezza e l'altezza
- Un getter
getAppName()che restituisce il nome - Un getter
getWindowSize()che restituisceDimensions - Un metodo
displayConfig()che stampa:"App: <name>, Window: <width>x<height>, Area: <area>"
main.cpp: mostra la differenza tra l'uso di struct e class. Leggi da input un nome per l'app, la larghezza e l'altezza (su tre righe separate), poi:- Crea direttamente una struct
Dimensionscon i valori di larghezza e altezza: accedi direttamente ai suoi membri per stampare:"Direct struct access: <width> x <height>" - Crea un oggetto
AppConfigcon tutti e tre i valori - Chiama
displayConfig()per mostrare la configurazione completa - Usa il getter per recuperare le dimensioni della finestra e stampare:
"Via getter - Area: <area>"
- Crea direttamente una struct
Questa sfida evidenzia la convenzione: usa struct quando hai dati semplici e trasparenti (come coordinate o dimensioni) e usa class quando vuoi controllare l'accesso e aggiungere comportamenti ai tuoi dati.
Converti gli input di larghezza e altezza da stringhe a interi usando std::stoi(). Non dimenticare le guardie di inclusione nel file header.
Provalo tu
#include <iostream>
#include <string>
#include "Config.h"
using namespace std;
int main() {
// Leggi l'input
string appName;
string widthStr;
string heightStr;
getline(cin, appName);
getline(cin, widthStr);
getline(cin, heightStr);
int width = stoi(widthStr);
int height = stoi(heightStr);
// TODO: Crea una struct Dimensions con width e height
// Accedi direttamente ai suoi membri per stampare: "Direct struct access: <width> x <height>"
// TODO: Crea un oggetto AppConfig con appName, width e height
// TODO: Chiama displayConfig() sull'oggetto AppConfig
// TODO: Usa il getter getWindowSize() per ottenere le dimensioni e stampare: "Via getter - Area: <area>"
return 0;
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniBuild e compilazione in C++File header e file sorgenteNamespace e ambitoIntroduzione alla programmazione orientata agli oggetti in C++Classi e oggetti a confrontoIl puntatore 'this'Metodi (funzioni membro)Attributi (membri dati)Fondamenti di costruttori e distruttoriRiepilogo - Calcolatrice semplice4Proprietà delle classi
Membri di istanza e staticiGetter e setterFunzioni membro constParola chiave mutableMetodi e variabili staticiFunzioni e classi friendRiepilogo - Gestore di conti bancari7Ereditarietà
Ereditarietà di baseLivelli di accesso nell’ereditarietàOrdine di chiamata di costruttori e distruttoriRidefinizione dei metodiFunzioni virtuali e VTableEreditarietà multiplaEreditarietà virtualeRiepilogo - Gerarchia dei dipendenti2Gestione della memoria
Memoria Stack vs HeapPuntatori e riferimentiMemoria dinamica (new/delete)Puntatori intelligenti in C++RAII in C++Riepilogo - Gestore di array dinamico5Incapsulamento
Specificatori di accesso in C++Specificatori di accesso in dettaglioOccultamento delle informazioniStruct vs classClassi annidate e interneRiepilogo - Sistema di registrazione degli studenti8Polimorfismo
Polimorfismo a compile time e a runtimeOverload delle funzioniFunzioni virtuali: ripassoFunzioni virtuali pureClassi astratteProgettazione delle interfacce in C++Dynamic casting e RTTIRipasso: calcolatrice di forme11Concetti avanzati di OOP
Composizione vs ereditarietàMixin tramite CRTPIdiom PimplType ErasureEnum class e tipizzazione forteGestione delle eccezioni in OOPGerarchie personalizzate di eccezioni14Pattern di progettazione - Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositeRAII come pattern3Costruttori e distruttori
Costruttore predefinitoCostruttore con parametriCostruttore di copiaCostruttore di spostamentoListe di inizializzazione dei costruttoriCostruttori delegantiApprofondimento sui distruttoriRegola del Tre / Cinque / ZeroRipasso - classe String6Sovraccarico degli operatori
Introduzione al sovraccarico degli operatoriSovraccarico degli operatori aritmeticiSovraccarico degli operatori di confrontoOperatori di flussoSovraccarico dell'operatore di assegnazioneSovraccarico degli operatori [] e ()Operatori di conversione di tipoRipasso - Classe Matrix9Template
Template di funzioneTemplate di classeSpecializzazione dei templateTemplate variadiciBasi di SFINAE e dei trait di tipoRiepilogo - Contenitore genericoEsercitati da solo: Compilatore C++ online