C / C ++ Struct vs Class


108

Dopo aver terminato la mia classe C ++ mi è sembrato che le strutture / classi fossero praticamente identiche tranne con alcune piccole differenze.

Non ho mai programmato in C prima; ma so che ha strutture. In C è possibile ereditare altre strutture e impostare un modificatore di public / private?

Se puoi farlo in C normale, perché nel mondo abbiamo bisogno di C ++? Cosa rende le classi diverse da una struttura?

c++  class  struct 


Risposte:


146

In C ++ , le strutture e le classi sono praticamente le stesse; l'unica differenza è che dove i modificatori di accesso (per le variabili membro, i metodi e le classi base) nelle classi vengono impostati di default su private, i modificatori di accesso nelle strutture vengono impostati su public.

Tuttavia, in C , una struttura è solo una raccolta aggregata di dati (pubblici) e non ha altre funzionalità di tipo classe: nessun metodo, nessun costruttore, nessuna classe base, ecc. Sebbene C ++ abbia ereditato la parola chiave, ha esteso la semantica. (Questo, tuttavia, è il motivo per cui le cose vengono impostate di default su public nelle strutture: una struttura scritta come una struttura in C si comporta come tale.)

Sebbene sia possibile falsificare un po 'di OOP in C, ad esempio definire funzioni che prendono tutte un puntatore a una struttura come primo parametro, o occasionalmente costringere le strutture con gli stessi primi campi a essere "sotto / superclassi", è sempre una specie di imbullonato, e non fa veramente parte della lingua.


Dai potenziali OOP .Net i ragazzi l'hanno definita in questo modo ✓ CONSIDERATE di definire una struttura invece di una classe se le istanze del tipo sono piccole e comunemente di breve durata o sono comunemente incorporate in altri oggetti. X EVITARE di definire una struttura a meno che il tipo non abbia tutte le seguenti caratteristiche: 1. Rappresenta logicamente un singolo valore, simile ai tipi primitivi (int, double, ecc.). 2. Ha una dimensione dell'istanza inferiore a 16 byte. 3. È immutabile.
Abhijeet

5
@Abhijeet Questa è la distinzione tra strutture e classi in C #, ma è semplicemente irrilevante per C ++, e ancor di più per C. In C #, classi e strutture sono effettivamente diverse; non è così in C ++, e C ha solo strutture senza OO.
Antal Spector-Zabusky

non sarebbe stato meglio mantenere la stessa semantica C in C ++ struct? e quando viene richiesto di usare una "struttura in modo c ++" usa semplicemente una classe? Non ho mai avuto il vantaggio di avere una struttura "aumentata" in C ++ rispetto a C. Mi piace ancora usare la struttura come progettata in C, altrimenti uso una classe, con qualche eccezione consentita.
Raffaello

15

A parte le differenze nell'accesso predefinito (pubblico / privato), non c'è differenza.

Tuttavia, alcuni negozi che il codice in C e C ++ useranno "class / struct" per indicare ciò che può essere utilizzato in C e C ++ (struct) e che sono solo C ++ (class). In altre parole, in questo stile tutte le strutture devono funzionare con C e C ++. Questo è il motivo per cui c'era una differenza in primo luogo molto tempo fa, quando il C ++ era ancora noto come "C con classi".

Nota che le unioni C funzionano con C ++, ma non il contrario. Per esempio

union WorksWithCppOnly{
    WorksWithCppOnly():a(0){}
    friend class FloatAccessor;
    int a;
private:
    float b;
};

E allo stesso modo

typedef union friend{
    int a;
    float b;
} class;

funziona solo in C


9
Usare parole chiave cpp nel codice c e poi affermare che non è compatibile con cpp è piuttosto stupido
Dani

7

Aggiungerò le risposte esistenti perché il moderno C ++ è ora una cosa e sono state create linee guida di base ufficiali per aiutare con domande come queste.

Ecco una sezione pertinente delle linee guida:

C.2: Usa classe se la classe ha un invariante; utilizzare struct se i membri dei dati possono variare indipendentemente

Un invariante è una condizione logica per i membri di un oggetto che un costruttore deve stabilire affinché le funzioni membro pubbliche assumano. Dopo che l'invariante è stato stabilito (in genere da un costruttore), ogni funzione membro può essere chiamata per l'oggetto. Un invariante può essere dichiarato informalmente (ad esempio, in un commento) o più formalmente utilizzando Expects.

Se tutti i membri dei dati possono variare indipendentemente l'uno dall'altro, non è possibile alcuna invariante.

Se una classe ha dati privati, un utente non può inizializzare completamente un oggetto senza l'uso di un costruttore. Quindi, il definitore della classe fornirà un costruttore e dovrà specificarne il significato. Ciò significa effettivamente che il definitore deve definire un invariante.

Rinforzo

Cerca strutture con tutti i dati privati ​​e classi con membri pubblici.

Gli esempi di codice forniti:

struct Pair {  // the members can vary independently
    string name;
    int volume;
};

// but

class Date {
public:
    // validate that {yy, mm, dd} is a valid date and initialize
    Date(int yy, Month mm, char dd);
    // ...
private:
    int y;
    Month m;
    char d;    // day
};

ClassFunzionano bene per i membri che, ad esempio, derivano l'uno dall'altro o sono correlati. Possono anche aiutare con il controllo della sanità mentale durante l'istanza. StructFunzionano bene per avere "sacchi di dati", in cui non succede niente di speciale ma i membri hanno logicamente senso essere raggruppati insieme.

Da questo, ha senso che classes esistano per supportare l'incapsulamento e altri concetti di codifica correlati, che structsemplicemente non sono molto utili.


Un'altra considerazione è la portabilità. structsono i più portatili. Possono essere usati da C o C ++ o avanti e indietro. Possono anche essere decompressi in Python usando il structmodulo, per esempio. Se i vostri priorità del progetto è compatibile con le altre lingue, interfacce o sistemi, preferiscono structsopra class. Per affari strettamente interni al programma, preferisci class.
Dave

6

Non è possibile definire funzioni membro o derivare strutture l'una dall'altra in C.

Inoltre, C ++ non è solo C + "derive structs". Modelli, riferimenti, spazi dei nomi definiti dall'utente e sovraccarico di operatori non esistono tutti in C.


So che i modelli, ecc. Non esistono in C ma non ero a conoscenza powerdegli struct in C. Quindi C ++ usa solo gli struct per essere 'retrocompatibili' con C?

4
Solo per compatibilità con le versioni precedenti? In pratica c'è probabilmente qualcosa in questo, ma la distinzione può essere un segnale di intenti: dove uso un structintendo un tipo di cosa POD largamente passivo.
dmckee --- gattino ex moderatore

@dmckee: per quello che vale, la maggior parte dei funtori STL (cioè std::less) sono definiti come strutture, non classi.
Billy ONeal

1
C ++ non è completamente compatibile con i backard C. Si potrebbe dire che la parola chiave struct è un accomodamento per gli sviluppatori C. Mi piace la parola chiave struct per le classi che contengono semplicemente i dati in modo ordinato ma non forniscono (molta) logica.
ypnos

@ypnos: vedi il mio ultimo commento. L'unica differenza tra i due è che i membri di uno sono pubblici di default e gli altri sono privati ​​di default.
Billy ONeal

3

Un'altra differenza in C ++, quando si eredita una classe da struct senza alcun identificatore di accesso, diventa un'eredità pubblica dove, come nel caso della classe, è un'eredità privata.


1

Il C ++ utilizza le strutture principalmente per 1) compatibilità all'indietro con i tipi C e 2) POD. Le strutture C non hanno metodi, ereditarietà o visibilità.


2
Per quel che vale, la maggior parte dei funtori STL (cioè std::less) sono definiti come strutture, non classi.
Billy ONeal

3
Nota che le strutture C ++ hanno metodi, ereditarietà e visibilità.
robertwb

c struct può includere puntatori a funzione anche se come type (* addr) (params);
Errore
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.