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


441

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

Ora vorrei imparare le differenze tra una struttura e una classe in C ++. Si prega di discutere le differenze tecniche e le ragioni per scegliere l'una o l'altra nella progettazione OO.

Inizierò con un'ovvia differenza:

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

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


6
Questo link riassume bene le differenze.
sjsam,

1
Perché allora tutti usano Struct per costruire un albero? Perché sembra che la differenza non sia molto. A proposito, questo è un ottimo sito Web. @ Sjsam
JW.ZG,

1
Cerchi la differenza tra structin C e C ++? Vedi qui .
Marc.2377

@ JW.ZG Non "tutte" le persone fanno! Coloro che lo fanno semplicemente preferiscono o non si rendono conto di cosa structsignifichi in C ++. ;) Ma non c'è motivo per cui non puoi usare la classparola chiave.
Corse di leggerezza in orbita

Risposte:


466

Dimentichi la delicata seconda differenza tra classi e strutture.

Abbandona lo standard (§11.2.2 in C ++ 98 fino a C ++ 11):

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

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

Il membro di una classe definita con la classe di parole chiave è privato per impostazione predefinita. I membri di una classe definita con le parole chiave struct o union sono pubbliche per impostazione predefinita.

Ulteriore differenza: la parola chiave classpuò essere utilizzata per dichiarare i parametri del modello, mentre la structparola chiave non può essere utilizzata così.


22
Non è davvero una seconda differenza, è solo che la domanda ha dichiarato la differenza in modo incompleto. Tutti gli oggetti secondari sono privati ​​per impostazione predefinita quando si utilizza class, public per impostazione predefinita con structed entrambi definiscono un tipo di classe.
Ben Voigt,

10
Penso che ti sia perso il punto, Ben. È l'eredità che è pubblica per le strutture e privata per le classi. Questa è una distinzione molto importante e completamente estranea all'accesso effettivo dei membri. Ad esempio, la lingua avrebbe potuto benissimo definirla diversamente, ad esempio entrambe sono ereditate pubblicamente per impostazione predefinita e si otterrebbero implicazioni molto diverse.
Assaf Lavie,

104
In realtà, la vera ingannevole differenza tra structed classè che quest'ultimo può essere utilizzato al posto di un typenameper dichiarare un parametro di template, mentre il primo non può. :)
sabato

21
@MrUniverse: questo è assolutamente sbagliato. (C'è una scuola che usa questo per un convegno, ma non è applicato sintatticamente.)
sbi,

3
@sbi "la vera differenza tra la struttura e la classe" - Carino, ma la domanda riguarda la differenza tra una struttura e una classe, non le differenze in cui le parole chiave possono essere utilizzate.
Jim Balter,

161

Citando le domande frequenti su C ++ ,

[7.8] Qual è la differenza tra la struttura delle parole chiave e la classe?

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

La struttura e la classe sono altrimenti funzionalmente equivalenti.

OK, abbastanza di quel discorso techno perfettamente pulito. Emotivamente, la maggior parte degli sviluppatori fa una forte distinzione tra una classe e una struttura. Una struttura sembra semplicemente una pila aperta di bit con molto poco 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. Dal momento che questa è la connotazione che molte persone hanno già, probabilmente dovresti 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.


123

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

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

Essere pubblici di default è generalmente considerato una cattiva idea quando si adotta un approccio orientato agli oggetti, quindi nel creare una forma di C che è nativamente favorevole a OOP (puoi fare OO in C, ma non ti aiuterà) che era il idea in C ++ (originariamente "C With Classes"), ha senso rendere i membri privati ​​per impostazione predefinita.

D'altra parte, se Stroustrup avesse cambiato la semantica in structmodo che i suoi membri fossero privati ​​per impostazione predefinita, avrebbe rotto la compatibilità (non è più vero quanto gli standard divergevano, ma tutti i programmi C validi erano anche programmi C ++ validi, che ha avuto un grande effetto nel dare un appoggio al C ++).

Quindi una nuova parola chiave, è classstata introdotta per essere esattamente come una struttura, ma privata per impostazione predefinita.

Se C ++ fosse venuto da zero, senza cronologia, probabilmente avrebbe una sola parola chiave. Probabilmente non avrebbe avuto l'impatto che ha avuto.

In generale, le persone tenderanno a usare struct quando stanno facendo qualcosa di simile a come le strutture sono usate in C; membri pubblici, nessun costruttore (fintanto che non è in un sindacato, puoi avere costruttori in strutture, proprio come con le classi, ma le persone tendono a non farlo), nessun metodo virtuale, ecc. Dal momento che le lingue sono tanto con cui comunicare le persone che leggono il codice per istruire le macchine (altrimenti dovremmo attenerci a assembly e codici operativi VM grezzi) è una buona idea attenersi a questo.


Probabilmente vale anche la pena notare che probabilmente era più facile avere classi e strutture che lavorassero allo stesso modo sotto il cofano, piuttosto che averle fondamentalmente diverse. In retrospettiva potrebbe esserci stato qualche vantaggio, ad esempio, specificare che qualsiasi cosa dichiarata come struct deve essere un PODS (ovvero vietare alle strutture di avere membri virtuali, costruttori o distruttori predefiniti non banali, ecc.) Ma una cosa del genere non è a mia conoscenza mai richiesto da alcuno standard C ++ né implementazione.
supercat

1
@supercat il fatto che fosse un linguaggio OO in cui un vasto repertorio di programmi scritti in un linguaggio non OO erano programmi validi, ha portato alla ribalta il concetto e sembra emergere più lì che in linguaggi OO più puramente (e ovviamente è definito nella norma). La storia dei primi C ++ spiega sicuramente molto a riguardo. "The Design and Evolution of C ++" di Stroustrup è una lettura interessante.
Jon Hanna,

1
Percepisco una guerra religiosa tra persone che sentono che tutto ciò che non è "oop-ish" dovrebbe essere e coloro che pensano che OOP debba essere considerato uno strumento, ma non lo strumento. Il C ++ sembra certamente abbracciare quest'ultima filosofia, ma in realtà non ne so molto delle lingue prima. La mia filosofia è che quando si desidera un oggetto si dovrebbe usare un oggetto e quando si desidera un'aggregazione di variabili correlate ma indipendenti, si dovrebbe usare quello. Il C ++ non fa alcuna distinzione sintattica tra questo tipo di cose, e .NET cerca di confondere quella distinzione, ma il poco che conosco di D ...
supercat

1
... suggerisce che lo riconosce più di C ++ o .NET. Le aggregazioni di variabili non sono esattamente OOPish, ma ciò non significa che non dovrebbero essere impiegate quando sono utili .
supercat

3
Non sono d'accordo con "C ha strutture, non ha il concetto di incapsulamento, quindi tutto è pubblico.", Puoi nascondere una definizione di un file structinterno *.ce lasciare che altre unità di traduzione lo utilizzino solo con un puntatore. Quindi hai un incapsulamento ancora più forte, perché altre unità di traduzione non sanno nemmeno cosa c'è dentro struct.
12431234123412341234123

32

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 .


15
Non solo membri, ma tutti gli accessi, inclusa l'eredità.
Nemanja Trifunovic,

4
Bene, direi che l'altra differenza è la semantica. Struct per molte persone li fa pensare alla "struttura dei dati" come un residuo di C.
Kris Kumler,

3
@KrisKumler: Quelli non sono "semantica"; sono sentimenti personali. Entrambi structe classdichiarano una classe con semantica identica (nonostante l'interpretazione parallela del corpo della definizione).
Corse di leggerezza in orbita,

28

Secondo Stroustrup nel linguaggio di programmazione C ++ :

Lo stile che usi dipende dalle circostanze e dal gusto. Di solito preferisco usare structper le classi che hanno tutti i dati pubblici. Penso a classi come "tipi non proprio corretti, solo strutture di dati".

Funzionalmente, non c'è differenza se non quella pubblica / privata


32
Che differenza? Spiega per favore.
crashmstr,

10

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ò spesso essere scritta nel file alla lettera. (ovvero Ottieni un puntatore alla struttura, usa la macro SIZE per calcolare il numero di byte da copiare, quindi sposta i dati dentro o fuori dalla struttura.)

Le classi sono un diverso tipo di tipo di dati astratto che tenta di nascondere le informazioni. Internamente, ci possono essere una varietà di macchinazioni, metodi, variabili temporanee, variabili di stato. ecc. che sono tutti utilizzati 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, devi capire che si tratta semplicemente di astrazioni. È perfettamente possibile creare strutture che assomigliano molto a classi e classi che assomigliano molto a strutture. In effetti, i primi compilatori C ++ erano semplicemente 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, Classes fornisce soluzioni al puzzle di denominazione del codice C. Poiché non è possibile avere più di una funzione esposta con lo stesso nome, gli sviluppatori seguivano un modello di _ (). ad esempio mathlibextreme_max (). Raggruppando le API in classi, funzioni simili (qui le chiamiamo "metodi") possono essere raggruppate e protette dalla denominazione dei metodi in altre classi. Ciò consente al programmatore di organizzare meglio il proprio codice e aumentare il riutilizzo del codice. In teoria, almeno.


1
Questa è la cosa più ovvia su strutture e classi. "Le strutture riguardano i dati, le classi riguardano il codice" può essere riformulato in quanto "le strutture riguardano i dati, le classi riguardano i dati, la sicurezza e le operazioni eseguite su questi dati"
Arun Aravind,

3
Non è possibile creare una struttura in C ++. È possibile creare una classe solo usando la structparola chiave ereditata .
Razze di leggerezza in orbita

1
Questa risposta non sembra riguardare il C ++. In C ++, structdichiara le classi (incluso public/ private/ protected, ereditarietà, ecc.).
melpomene,

Come sono astratte le strutture? La scrittura di strutture non elaborate su un file è piena di problemi anche in C (i soliti problemi includono riempimento, endianness, dimensioni delle parole diverse, ecc.). Di che SIZEmacro stai parlando?
melpomene,

10

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 ricava una struttura da una classe / struttura, l'identificatore di accesso predefinito per una classe / struttura di base è pubblico. E quando deriva una classe, l'identificatore di accesso predefinito è privato.

Ad esempio il programma 3 fallisce nella compilazione e il programma 4 funziona bene.

// 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;
}

Ho rimosso esempi di codice 3-7, come menzionato dagli esperti
Suraj K Thomas,

8

L'unica altra differenza è l'ereditarietà predefinita di classi e strutture, che, ovviamente, è privata e pubblica rispettivamente.


5
  1. I membri di una struttura sono pubblici per impostazione predefinita, i membri della classe sono privati ​​per impostazione predefinita.
  2. L'eredità predefinita per la struttura da un'altra struttura o classe è pubblica. L'eredità 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.


_tmainnon è C ++ standard.
melpomene,

4

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


4

Un'altra cosa da notare, se hai aggiornato un'app legacy che aveva delle strutture per usare le classi potresti riscontrare il seguente problema:

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

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

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


1
Il codice che utilizza memfill per cancellare una struttura ha probabilmente altre abitudini offensive. Vai con cautela.
David Thornley,

@DavidThornley: l'uso di un riempimento zero per cancellare o inizializzare una struttura di dati è standard in C. In un progetto in lingua mista, non ci si può aspettare che il codice nella parte C eviti calloca favore new. Tutto ciò che si può fare è cercare di assicurarsi che tutte le strutture utilizzate dalla parte C del codice siano in realtà PODS.
supercat

4
  1. I membri di una classe definita con la parola chiave classsono privatepredefiniti. I membri di una classe definita con le parole chiave struct(o union) sono publicpredefiniti.

  2. In assenza di un identificatore di accesso per una classe di base, publicviene assunto quando viene dichiarata la classe derivatastruct e privateviene assunto quando viene dichiarata la classe class.

  3. Puoi dichiarare un enum classma non un enum struct.

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

Si noti inoltre che lo standard C ++ consente di dichiarare in avanti un tipo come a struct, quindi utilizzarlo classper dichiarare il tipo e viceversa. Inoltre, std::is_class<Y>::valueè trueper Y essere un structe un class, ma è falseper un enum class.


bella risposta, anche se mi manca un chiaro inconfondibile 0) la differenza tra structe classin c ++ è una differenza tra parole chiave, non tra tipi di dati (o qualche alternativa migliore;)
idclev 463035818

@ formerlyknownas_463035818: Ma non pensi std::is_class<Y>::valueche lo copra?
Bathsheba,

sì, ho pensato che potesse essere più importante, perché questo è il malinteso comune e una volta che è fuori mano il resto è solo corollario.
idclev 463035818

Non importa, la tua risposta è perfetta così com'è, ne ho scritto un altro, non fa male averne uno in più
idclev 463035818

4

La differenza tra classe structè una differenza tra parole chiave, non tra tipi di dati. Questo due

struct foo : foo_base { int x;};
class bar : bar_base { int x; };

entrambi definiscono un tipo di classe. La differenza delle parole chiave in questo contesto è il diverso accesso predefinito:

  • foo::xè pubblico ed foo_baseè ereditato pubblicamente
  • bar::xè privato ed bar_baseè ereditato privatamente

2

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

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


2

È solo una convention. Le strutture possono essere create per contenere dati semplici ma successivamente evolvono il tempo con l'aggiunta di funzioni e costruttori dei membri. D'altra parte è insolito vedere qualcosa di diverso dal pubblico: accesso in una struttura.


2

ISO IEC 14882-2003

9 classi

§3

Una struttura è una classe definita con la chiave di classe struct ; i suoi membri e le classi base (clausola 10) sono di default pubblici (clausola 11).


2

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

1
Se hai intenzione di sottolineare che le strutture non possono essere utilizzate come tipi generalizzati, allora hai torto. E structnon è consentito lì solo per convenzione (meglio dire che è la classparola chiave che viene utilizzata in diversi sensi qui, vedi Usa 'class' o 'typename' per i parametri del template ).
dma_k,

La parola chiave non è consentita lì, ma puoi passare in una classe che hai definito structbene. Provalo e basta. struct T{}; template <typename T> void foo() {} foo<T>();
Razze di leggerezza in orbita,

1

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

Ciò che potrebbe essere interessante notare (in particolare poiché è probabile che il richiedente stia utilizzando MSVC ++ poiché menziona C ++ "non gestito") è che Visual C ++ si lamenta in determinate circostanze se una classe viene dichiarata con classe quindi definita con struct(o forse viceversa) ), sebbene lo standard affermi che è perfettamente legale.


So che è un commento molto tardivo, ma tieni presente che il suddetto avvertimento non è privo di merito poiché le ABI di Windows strutturano le classi e le classi in modo diverso e quindi mescolare dichiarazioni (in avanti) di classe e struttura può effettivamente portare a problemi di collegamento difficili da comprendere!
MFH,

1
  • . Nelle classi tutti i membri per impostazione predefinita sono privati ​​ma nella struttura i membri sono pubblici per impostazione predefinita.

    1. Non esiste un termine come costruttore e distruttore per le strutture, ma per il compilatore di classi viene creato un valore predefinito se non viene fornito.

    2. La dimensione della struttura vuota è di 0 byte poiché la dimensione della classe vuota è di 1 byte Il tipo di accesso predefinito struct è pubblico. Una struttura dovrebbe in genere essere utilizzata per raggruppare i dati.

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

    In breve, la convenzione è di usare struct quando lo scopo è quello di raggruppare i dati e usare le classi quando abbiamo bisogno di astrazione dei dati e, forse, ereditarietà.

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


3
"2. La dimensione della struttura vuota è di 0 byte poiché la dimensione della classe vuota è di 1 byte". Falso. Ho appena provato con g++. Potresti pensare all'ottimizzazione della base vuota, ma questo vale anche per entrambi.
cdunn2001,

1
Non vero. In C ++ la dimensione di una struttura vuota è 1. In C una struttura vuota non è consentita. GCC consente strutture vuote in C come estensione del compilatore e tale struttura ha dimensione 0.
Johan Råde

Questa risposta è sbagliata Oltre alla dimensione, anche la parte costruttore / distruttore è imprecisa: le strutture possono avere costruttori e distruttori benissimo. In effetti, structcrea classi a tutti gli effetti in C ++.
melpomene,

1

Sebbene implicito da altre risposte, non è esplicitamente menzionato - che le strutture sono C compatibili, a seconda dell'uso; le classi no.

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


-1

Si potrebbe considerare questo per le linee guida su quando andare per struct o class, https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx .

√ CONSIDERANDO la definizione di una struttura anziché 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:

Rappresenta logicamente un singolo valore, simile ai tipi primitivi (int, double, ecc.).

Ha una dimensione dell'istanza inferiore a 16 byte.

È immutabile

Non dovrà essere inscatolato frequentemente.


Si tratta di .NET / C #, non di C ++.
melpomene,

-2

La classe ha senso solo nel contesto dell'ingegneria del software. Nel contesto delle strutture dati e degli algoritmi, classe e struttura non sono così diverse. Non esiste alcuna regola limitata a cui deve essere fatto riferimento il membro della classe.

Quando si sviluppa un progetto di grandi dimensioni con tonnellate di persone senza classe, si può finalmente ottenere un codice accoppiato complicato perché tutti usano qualsiasi funzione e dato desiderino. class fornisce controlli di autorizzazione ed elementi inerenti per migliorare il disaccoppiamento e il riutilizzo dei codici.

Se leggi alcuni principi di ingegneria del software, scoprirai che la maggior parte degli standard non può essere implementata facilmente senza classe. ad esempio: http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29

A proposito, quando una struttura alloca uno scricchiolio della memoria e include diverse variabili, le variabili del tipo di valore indicano che i valori sono incorporati nel punto in cui è allocata la struttura. Al contrario, i valori della variabile del tipo di riferimento sono esterni e riferimento da un puntatore incorporato anche nel punto in cui viene allocata la struttura.


Questa risposta non sembra riguardare il C ++. In C ++, structdichiara le classi (inclusi controlli di autorizzazione, ereditarietà, ecc.).
melpomene,

-3

La differenza tra le parole chiave struct e class in C ++ è che, quando non esiste uno specifico specificatore su un particolare tipo di dati compositi, per impostazione predefinita struct o union sono le parole chiave pubbliche che considerano semplicemente il nascondimento dei dati ma class è la parola chiave privata che considera il nascondimento del programma codici o dati. Alcuni programmatori usano sempre struct per i dati e la classe per motivi di codice. Per ulteriori informazioni contattare altre fonti.


OP lo ha già menzionato struct membri sono pubblici per impostazione predefinita e la risposta accettata dal 2009 menziona l'eredità. Perché scrivere un'altra risposta che non aggiunge nuove informazioni 4 anni dopo?
melpomene,

-3

Di tutti questi fattori, si può concludere che il concetto di Classe è altamente adatto a rappresentare oggetti del mondo reale piuttosto che "Strutture". Probabilmente perché i concetti di OOP usati in classe sono altamente pratici nello spiegare scenari di mondo reale, quindi è più facile fonderli con la realtà. Ad esempio, l'ereditarietà predefinita è pubblica per le strutture ma se applichiamo questa regola per il mondo reale, è ridicola, ma in una classe l'eredità predefinita è privata che è più realistica.

Comunque, ciò che devo giustificare è che Class è un concetto molto più ampio e applicabile nel mondo reale, mentre la Struttura è un concetto primitivo con scarsa organizzazione interna (anche se la struttura segue i concetti OOP, hanno un significato scarso)


1
In che modo l'eredità privata è "più realistica"? La maggior parte dei linguaggi di programmazione non ha nemmeno il concetto di eredità privata.
melpomene,

-3

La differenza principale tra struttura e parola chiave class in oops è che nessuna struttura pubblica e privata è presente nella struttura. E la funzione membro membro e membro può essere definita come pubblica, privata e protetta.


Questa risposta non sembra riguardare il C ++. In C ++, structdichiara le classi (incluso public/ private/ protected, ereditarietà, ecc.).
melpomene,

-3

** AGGIORNAMENTO: ** Si prega di ignorare questa risposta. Non ho considerato la possibilità che per la struttura il valore non fosse inizializzato, ma era appena pari a 0. Non esiste una differenza di inizializzazione tra la struttura e la classe.


Vedo un'altra differenza tra le strutture e le classi che hanno a che fare con l'inizializzazione predefinita.

struct Foo {
    int a;
};

class Bar {
    int a;
};

class Tester {
    Foo m_Foo = Foo();
    Bar m_Bar = Bar();

public:
    Tester() {}
};

int main() {
    auto myTester = Tester();
}

Esegui quel codice ed esamina myTester. Scoprirai che per m_Foo, la struttura, m_Foo.a è stata inizializzata su 0, ma per m_Bar, la classe, m_Bar.a non è inizializzata. Quindi sembra esserci una differenza in ciò che fa il costruttore predefinito per struct vs. class. Lo vedo con Visual Studio.


1
Come hai stabilito che m_Foo.aera stato inizializzato? E se non fosse stato inizializzato e fosse successo 0?
melpomene,

Uhhh, non l'ho fatto. Colpa mia. Questa non è una differenza tra struct e class. Le caratteristiche di inizializzazione sono le stesse.
Eric Hill

-4

La differenza principale tra struct e class è che in struct puoi dichiarare solo variabili di dati di diversi tipi di dati mentre in class puoi dichiarare variabili di dati, funzioni membro e quindi puoi manipolare variabili di dati attraverso funzioni.

-> un'altra cosa utile che trovo in class vs struct è che durante l'implementazione dei file in un programma se si desidera eseguire alcune operazioni di una struttura ancora e ancora su ogni nuovo set di operazioni è necessario creare una funzione separata e è necessario passa l'oggetto di struct dopo averlo letto dal file in modo da effettuare alcune operazioni su di esso. mentre sei in classe se fai una funzione che fa ogni volta alcune operazioni sui dati necessari..e facile, devi solo leggere l'oggetto dal file e chiamare la funzione ..

Ma dipende dal programmatore nel modo in cui lo trova adatto ... secondo me preferisco la classe ogni volta solo perché supporta gli OOP e questo è il motivo per cui è implementato in quasi tutte le lingue ed è la meravigliosa caratteristica della programmazione di tutti i tempi; - )

E sì, la differenza più impercettibile che ho dimenticato di menzionare è che la classe supporta il nascondimento dei dati e supporta anche le operazioni che vengono eseguite su tipi di dati incorporati mentre struct non lo fa!


1
In C ++ structpossono avere funzioni membro
chtz

@chtz Grazie ... ho avuto modo di conoscere questa funzione proprio ora .. grazie mille .. Sono solo un principiante non così esperto come te, quindi in futuro ho bisogno anche di consigli da parte di voi ragazzi :-)
Yug Rawal

e in effetti, la funzione membro deve essere intesa nel suo significato più ampio. structpuò avere costruttori, funzione membro e distruttore (possibilmente virtuale, possibilmente privato, protetto o pubblico). Possono ereditare ed essere ereditati. quindi in realtà ... tutto ciò che una classe può avere. una convenzione tipica è quella di dichiarare con struct ciò che avresti dichiarato come struct in C e come classe se dichiarassimo variabili private e protette, funzioni virtuali, ctor e dtor e così via. Ma è solo una convenzione, non applicata dalla lingua
Gian Paolo,

-5

Ho trovato un'altra differenza. se non si definisce un costruttore in una classe, il compilatore ne definirà uno. ma in una struttura se non si definisce un costruttore, anche il compilatore non definisce un costruttore. quindi in alcuni casi che non abbiamo davvero bisogno di un costruttore, la struttura è una scelta migliore (suggerimento sulle prestazioni). e scusami per il mio cattivo inglese.


4
Questo non è vero. Non vi è alcuna differenza tra una classe definita con la structparola chiave e una classe definita con la classparola chiave in questo senso.
ymett,

quando uso uno struct senza un costruttore, ottengo una velocità migliore di una classe senza un costruttore.
Ali,

@Ali No, non lo fai.
Corse di leggerezza in orbita

-5

Le classi sono tipi di riferimento e le strutture sono tipi di valori.
Quando dico che le classi sono tipi di riferimento,
fondamentalmente conterranno l'indirizzo di una variabile di istanza.

Per esempio:

Class MyClass
{
    Public Int DataMember;  //By default, accessibility of class data members 
                            //will be private. So I am making it as Public which 
                            //can be accessed outside of the class.
}

Nel metodo principale,
posso creare un'istanza di questa classe utilizzando un nuovo operatore che alloca memoria per questa classe
e memorizza l'indirizzo di base di tale nella variabile di tipo MyClass (_myClassObject2).

Static Public void Main (string[] arg)
{
    MyClass _myClassObject1 = new MyClass();
    _myClassObject1.DataMember = 10;

    MyClass _myClassObject2 = _myClassObject1;
    _myClassObject2.DataMember=20;
}

Nel programma sopra, MyClass _myClassObject2 = _myClassObject1; l'istruzione indica che entrambe le variabili di tipo MyClass

  1. myClassObject1
  2. myClassObject2

e indicherà la stessa posizione di memoria.
In pratica assegna la stessa posizione di memoria in un'altra variabile dello stesso tipo.

Pertanto, se qualsiasi modifica apportata a uno qualsiasi degli oggetti, digitare MyClass avrà un effetto su un altro
poiché entrambi puntano alla stessa posizione di memoria.

"_myClassObject1.DataMember = 10;" su questa riga entrambi i membri dei dati dell'oggetto conterranno il valore di 10.
"_myClassObject2.DataMember = 20;" su questa riga entrambi i membri dei dati dell'oggetto conterranno il valore di 20.
Alla fine, accediamo ai membri di un oggetto tramite puntatori.

A differenza delle classi, le strutture sono tipi di valore. Per esempio:

Structure MyStructure
{
    Public Int DataMember;  //By default, accessibility of Structure data 
                            //members will be private. So I am making it as 
                            //Public which can be accessed out side of the structure.
}

Static Public void Main (string[] arg)
{
    MyStructure _myStructObject1 = new MyStructure();
    _myStructObject1.DataMember = 10;

    MyStructure _myStructObject2 = _myStructObject1;
    _myStructObject2.DataMember = 20;
}

Nel programma precedente,
creare un'istanza dell'oggetto di tipo MyStructure usando un nuovo operatore e
memorizzare l'indirizzo nella variabile _myStructObject di tipo MyStructure e
assegnare il valore 10 al membro dati della struttura utilizzando "_myStructObject1.DataMember = 10".

Nella riga successiva,
sto dichiarando un'altra variabile _myStructObject2 di tipo MyStructure e assegnando _myStructObject1.
Qui il compilatore .NET C # crea un'altra copia dell'oggetto _myStructureObject1 e
assegna tale posizione di memoria nella variabile MyStructure _myStructObject2.

Pertanto, qualsiasi modifica apportata a _myStructObject1 non avrà mai effetto su un'altra variabile _myStructObject2 di tipo MyStructrue.
Ecco perché stiamo dicendo che le strutture sono tipi di valore.

Quindi la classe Base immediata per la classe è Object e la classe Base immediata per Structure è ValueType che eredita da Object.
Le classi sosterranno un'eredità mentre le strutture no.

Come lo stiamo dicendo?
E qual è la ragione dietro questo?
La risposta è Classi.

Può essere astratto, sigillato, statico e parziale e non può essere interno privato, protetto e protetto.


4
Penso che questo stia cercando di rispondere alla domanda per c #? La domanda riguarda c ++ e questo rende inaccurata questa risposta, giusto?
smw

@smw assolutamente, ha scritto il suo codice di esempio in C # e sono venuto qui per verificare che non ci fosse differenza nel parametro che passa tra C ++ structe class. Nessuno qui lo ha menzionato, né l'intera rete. Quindi non penso che questo si applichi nemmeno al C ++.
Giovanni,

Questo non è nemmeno un codice C # valido: le parole chiave sono tutte sbagliate. "Pubblico", "Statico", "Int" e "Classe" non devono essere scritti in maiuscolo e dovrebbero essere "struct" e non "Structure". La descrizione è per lo più accurata per C # (anche se le strutture possono ancora ereditare interfacce, ma non altre strutture), ma non risponde alla domanda poiché si trattava di C ++ ...
Darrel Hoffman,

2
Questa risposta è completa senza senso. Usa uno strano mix di Visual Basic e C # per i suoi esempi di codice, e l'intero "Classi sono tipi di riferimento e Strutture sono tipi di valori" ... la cosa vale solo per .NET (cioè C #) e non per C ++. Sei nella stanza sbagliata, amico. Questo è dove si appartiene: stackoverflow.com/questions/13049
TheFlash

Ma questa risposta indica che lo stesso vale per C (++), che le strutture sono usate come tipi di valore. int a = 3; int b = a;e similiMyStruct a=MyStruct("data"); MyStruct b = a;
luckydonald

-8

Esistono 3 differenze di base tra struttura e classe

La memoria 1St è riservata per la struttura nella memoria dello stack (che è vicina al linguaggio di programmazione) se per la classe nella memoria dello stack è riservata solo la reffrenza e la memoria effettiva è riservata nella memoria dell'heap.

2 ° - Per impostazione predefinita, la struttura tratta come pubblico se la classe tratta come privata.

3Rd- non è possibile riutilizzare il codice nella struttura, ma in classe possiamo riutilizzare lo stesso codice in molti casi chiamato eredità


2
Le strutture C ++ supportano l'ereditarietà e i metodi astratti. La struttura e la classe sono assegnate allo stesso modo. Allocare classe sull'heap anche se non sono istanziati con un "nuovo" non ha senso per i sistemi embedded.
JCMS

2
# 1 è anche sbagliato. Lo stack viene utilizzato quando si dichiara qualcosa di quel tipo come variabile locale e l'heap viene utilizzato quando si utilizza il "nuovo" operatore.
Score_Under
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.