it-swarm-eu.dev

Quali sono le differenze tra struct e class in C ++?

Questa domanda era già posta nel contesto di C # /. Net .

Ora mi piacerebbe imparare le differenze tra una struct e una classe in C++. Si prega di discutere le differenze tecniche e le ragioni per scegliere l'una o l'altra in OO design.

Inizierò con un'evidente differenza:

  • Se non si specifica public: o private:, i membri di una struct sono pubblici per impostazione predefinita; i membri di una classe sono privati ​​per impostazione predefinita.

Sono sicuro che ci sono altre differenze da trovare negli angoli oscuri della specifica C++.

414
palm3D

Dimentichi la difficile seconda differenza tra classi e strutture.

Lo standard (§11.2.2 in C++ 98 a C++ 11):

In assenza di un identificatore di accesso per una classe base, si assume il pubblico quando la classe derivata è dichiarata struct e privato è assunto quando la classe è dichiarata class .

E solo per completezza, la differenza più nota tra classe e struttura è definita in (11.2):

I membri di una classe definita con la parola chiave class sono private per impostazione predefinita. I membri di una classe definita con le parole chiave struct o union sono public per impostazione predefinita.

Ulteriore differenza: la parola chiave class può essere utilizzata per dichiarare i parametri del modello, mentre la parola chiave struct non può essere utilizzata in questo modo.

449
Assaf Lavie

Citando Le domande frequenti su C++ ,

[7.8] Qual è la differenza tra le parole chiave struct e class?

I membri e le classi base di una struct sono pubblici per impostazione predefinita, mentre in classe, per impostazione predefinita sono privati. Nota: è necessario rendere le classi di base esplicitamente pubbliche, private o protette, piuttosto che fare affidamento sui valori predefiniti.

La struttura e la classe sono altrimenti equivalenti dal punto di vista funzionale.

Ok, abbastanza di quel chiacchiericcio pulito e techno. Emotivamente, la maggior parte degli sviluppatori fa una forte distinzione tra una classe e una struttura. Una struttura si sente semplicemente come una pila aperta di bit con pochissimo in termini di incapsulamento o funzionalità. Una classe si sente come un membro vivente e responsabile della società con servizi intelligenti, una forte barriera di incapsulamento e un'interfaccia ben definita. Poiché questa è la connotazione che la maggior parte delle persone già possiede, dovresti probabilmente usare la parola chiave struct se hai una classe che ha pochissimi metodi e ha dati pubblici (cose del genere esistono in sistemi ben progettati!), Ma altrimenti dovresti probabilmente usare la classe parola chiave.

157
Robᵩ

Vale la pena ricordare le origini di C++ e la compatibilità con C.

C ha strutture, non ha alcun concetto di incapsulamento, quindi tutto è pubblico.

Essere pubblico di default è generalmente considerato una cattiva idea quando si prende un approccio orientato agli oggetti, quindi nel creare una forma di C che sia nativamente favorevole a OOP (si può fare OO in C , ma non ti aiuterà) che era l'idea in C++ (originariamente "C With Classes"), ha senso rendere i membri privati ​​di default.

D'altra parte, se Stroustrup avesse cambiato la semantica di struct in modo che i suoi membri fossero privati ​​di default, avrebbe rotto la compatibilità (non è più così spesso come gli standard divergevano, ma tutti i programmi C validi erano anche programmi C++ validi , che ha avuto un grande effetto nel dare un punto d'appoggio a C++).

Quindi una nuova parola chiave, class è stata introdotta per essere esattamente come una struct, ma privata di default.

Se il C++ fosse venuto da zero, senza cronologia, probabilmente avrebbe una sola parola chiave del genere. Probabilmente anche non avrebbe reso l'impatto che ha fatto.

In generale, le persone tendono a usare struct quando fanno qualcosa come come le strutture sono usate in C; membri pubblici, nessun costruttore (purché non sia in un sindacato, tu puoi avere costruttori nelle strutture, proprio come con le classi, ma le persone tendono non a), nessun metodo virtuale, ecc. Dal momento che le lingue sono tanto comunicative con le persone che leggono il codice quanto istruiscono le macchine (oppure ci limiteremmo con Assembly e raw VM opcodes) è una buona idea attenersi a quello.

115
Jon Hanna

I membri della classe sono privati ​​per impostazione predefinita. I membri di Struct sono pubblici per impostazione predefinita. Oltre a ciò non ci sono altre differenze. Vedi anche questa domanda .

31
Kasprzol

Secondo Stroustrup nel linguaggio di programmazione C++ :

Quale stile usi dipende dalle circostanze e dal gusto. Di solito preferisco usare struct per le classi che hanno tutti i dati pubblici. Penso a classi come "tipi non proprio adeguati, solo strutture dati".

Funzionalmente, non c'è altra differenza rispetto al pubblico/privato

28
crashmstr

STRUCT è un tipo di tipo di dati astratto che divide un determinato blocco di memoria in base alle specifiche della struttura. Le strutture sono particolarmente utili nella serializzazione/deserializzazione dei file poiché la struttura può essere spesso scritta nel file letteralmente. (Ad esempio, ottenere un puntatore alla struttura, utilizzare la macro SIZE per calcolare il numero di byte da copiare, quindi spostare i dati all'interno o all'esterno della struttura.)

Le classi sono un diverso tipo di tipo di dati astratti che cercano di garantire l'occultamento delle informazioni. Internamente, ci possono essere una varietà di macchinazioni, metodi, variabili temporali, variabili di stato. ecc. che sono tutti usati per presentare un'API coerente a qualsiasi codice che desideri utilizzare la classe.

In effetti, le strutture riguardano i dati, le classi riguardano il codice.

Tuttavia, è necessario comprendere che si tratta semplicemente di astrazioni. È perfettamente possibile creare strutture che assomigliano molto a classi e classi che assomigliano molto alle strutture. In effetti, i primi compilatori C++ erano solo pre-compilatori che traducono il codice C++ in C. Quindi queste astrazioni sono un vantaggio per il pensiero logico, non necessariamente una risorsa per il computer stesso.

Oltre al fatto che ognuno è un diverso tipo di astrazione, le Classi forniscono soluzioni al puzzle di denominazione del codice C. Dato che non è possibile avere più di una funzione esposta con lo stesso nome, gli sviluppatori hanno seguito uno schema di _ (). per esempio. mathlibextreme_max (). Raggruppando le API in classi, funzioni simili (qui li chiamiamo "metodi") possono essere raggruppate e protette dalla denominazione dei metodi in altre classi. Ciò consente al programmatore di organizzare meglio il suo codice e aumentare il riutilizzo del codice. In teoria, almeno.

9
64BitBob

1) I membri di una classe sono privati ​​per impostazione predefinita e i membri di struct sono pubblici per impostazione predefinita.

Ad esempio, il programma 1 non riesce nella compilazione e il programma 2 funziona correttamente.

// Program 1
#include <stdio.h>

class Test {
    int x; // x is private
};
int main()
{
  Test t;
  t.x = 20; // compiler error because x is private
  getchar();
  return 0;
}
Run on IDE
// Program 2
#include <stdio.h>

struct Test {
    int x; // x is public
};
int main()
{
  Test t;
  t.x = 20; // works fine because x is public
  getchar();
  return 0;
}

2) Quando si deriva una struct da una classe/struct, l'identificatore di accesso predefinito per una classe/struct di base è pubblico. E quando si ottiene una classe, l'identificatore di accesso predefinito è privato.

Ad esempio, il programma 3 non riesce nella compilazione e il programma 4 funziona correttamente.

// Program 3
#include <stdio.h>

class Base {
public:
    int x;
};

class Derived : Base { }; // is equilalent to class Derived : private Base {}

int main()
{
  Derived d;
  d.x = 20; // compiler error becuase inheritance is private
  getchar();
  return 0;
}
Run on IDE
// Program 4
#include <stdio.h>

class Base {
public:
    int x;
};

struct Derived : Base { }; // is equilalent to struct Derived : public Base {}

int main()
{
  Derived d;
  d.x = 20; // works fine becuase inheritance is public
  getchar();
  return 0;
}
9
Suraj K Thomas

L'unica altra differenza è l'ereditarietà predefinita di classi e strutture, che, ovviamente, sono private e pubbliche rispettivamente.

8
Skizz
  1. I membri di una struttura sono pubblici per impostazione predefinita, i membri della classe sono privati ​​per impostazione predefinita.
  2. L'ereditarietà predefinita di Structure da un'altra struttura o classe è pubblica. L'ereditarietà predefinita per la classe da un'altra struttura o classe è privata.
class A{    
public:    
    int i;      
};

class A2:A{    
};

struct A3:A{    
};


struct abc{    
    int i;
};

struct abc2:abc{    
};

class abc3:abc{
};


int _tmain(int argc, _TCHAR* argv[])
{    
    abc2 objabc;
    objabc.i = 10;

    A3 ob;
    ob.i = 10;

    //A2 obja; //privately inherited
    //obja.i = 10;

    //abc3 obss;
    //obss.i = 10;
}

Questo è su VS2005.

4
GirishNayak

Un'altra cosa da notare, se hai aggiornato un'app legacy con le strutture in cui utilizzare le classi, potresti avere il seguente problema:

Il vecchio codice ha le strutture, il codice è stato ripulito e questi sono stati modificati in classi. Una o due funzioni virtuali sono state quindi aggiunte alla nuova classe aggiornata.

Quando le funzioni virtuali sono nelle classi, internamente il compilatore aggiungerà un puntatore aggiuntivo ai dati della classe per puntare alle funzioni.

Il modo in cui questo romperebbe il vecchio codice legacy è se nel vecchio codice da qualche parte la struttura è stata cancellata usando memfill per cancellare tutto a zero, questo potrebbe calpestare anche i dati del puntatore extra.

4
KPexEA

Non nelle specifiche, no. La principale differenza è nelle aspettative dei programmatori quando leggono il tuo codice in 2 anni. le strutture sono spesso considerate POD. Le strutture vengono anche utilizzate nella metaprogrammazione del modello quando si definisce un tipo per scopi diversi dalla definizione di oggetti.

4
MSalters

Un'altra differenza principale è quando si tratta di modelli. Per quanto ne so, puoi usare una classe quando definisci un modello ma NON una struttura.

template<class T> // OK
template<struct T> // ERROR, struct not allowed here
3
Stefan Popescu

È solo una convenzione. Le strutture possono essere create per contenere dati semplici, ma in seguito si evolvono i tempi con l'aggiunta di funzioni membro e costruttori. D'altra parte è insolito vedere qualcosa di diverso dal pubblico: l'accesso in una struttura.

2
finnw

ISO IEC 14882-2003

9 lezioni

§3

Una struttura è una classe definita con class-key struct; i suoi membri e le classi di base (clausola 10) sono pubblici per impostazione predefinita (clausola 11).

2
Gregory Pakosz
  1. I membri di una classe definita con la parola chiave class sono private per impostazione predefinita. I membri di una classe definita con le parole chiave struct (o union) sono public per impostazione predefinita.

  2. In assenza di un identificatore di accesso per una classe base, si assume public quando la classe derivata è dichiarata struct e private è assunta quando la classe è dichiarata class .

  3. Puoi dichiarare un enum class ma non un enum struct.

  4. Puoi usare template<class T> ma non template<struct T>.

Si noti inoltre che lo standard C++ consente di inoltrare un tipo come struct e quindi utilizzare class quando si dichiara il tipo e viceversa. Inoltre, std::is_class<Y>::value è true perché Y è un struct e un class, ma false per un enum class.

2
Bathsheba

Ecco una buona spiegazione: http://carcino.gen.nz/tech/cpp/struct_vs_class.php

Quindi, ancora una volta: in C++, una struct è identica a una classe tranne che i membri di una struct hanno visibilità pubblica per impostazione predefinita, ma i membri di una classe hanno visibilità privata per impostazione predefinita.

2
nutario
  • . Nelle classi tutti i membri per impostazione predefinita sono privati ​​ma i membri della struttura sono pubblici per impostazione predefinita.

    1. Non esiste un termine come costruttore e distruttore per le strutture, ma per il compilatore di classi crea un valore predefinito se non lo si fornisce.

    2. La dimensione della struttura vuota è 0 byte come dimensione della classe vuota è 1 byte Il tipo di accesso predefinito della struttura è pubblico. In genere una struct deve essere utilizzata per raggruppare i dati.

    Il tipo di accesso predefinito della classe è privato e la modalità predefinita per l'ereditarietà è privata. Una classe deve essere utilizzata per raggruppare dati e metodi che operano su tali dati.

    In breve, la convenzione consiste nell'utilizzare struct quando lo scopo è raggruppare i dati e utilizzare le classi quando si richiede l'astrazione dei dati e, forse, l'ereditarietà.

    In C++, le strutture e le classi vengono passate per valore, a meno che non vengano de-referenziati in modo esplicito. In altre lingue le classi e le strutture possono avere una semantica distinta, ad es. oggetti (istanze di classi) possono essere passati per riferimento e le strutture possono essere passati per valore. Nota: ci sono commenti associati a questa domanda. Vedi la pagina di discussione per aggiungere alla conversazione.

1
yshivakathik

Mentre è implicito in altre risposte, non è esplicitamente menzionato - che le strutture sono compatibili con C, a seconda dell'utilizzo; le classi non lo sono.

Questo significa che se stai scrivendo un'intestazione che vuoi essere compatibile con C, non hai altra scelta che struct (che nel mondo C non può avere funzioni, ma può avere dei puntatori di funzione).

1
UKMonkey

Le altre risposte hanno menzionato le impostazioni predefinite private/pubbliche, (ma si noti che una struttura è una classe è una struttura, non sono due elementi diversi, solo due modi per definire lo stesso elemento).

Ciò che potrebbe essere interessante notare (in particolare dal momento che il richiedente sta probabilmente usando MSVC++ poiché menziona C++ "non gestito") è che Visual C++ si lamenta in determinate circostanze se una classe è dichiarata con class e quindi definita con struct (o forse l'altra modo rotondo), anche se lo standard dice che è perfettamente legale.

1
ymett