Domanda

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

Ora mi piacerebbe imparare le differenze tra una struttura e una classe in C++.Si prega di discutere le differenze tecniche e i motivi per scegliere l'uno o l'altro nella progettazione OO.

Inizierò con una differenza evidente:

  • Se non lo specifichi 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 siano altre differenze da trovare negli angoli oscuri delle specifiche C++.

È stato utile?

Soluzione

Dimentichi la complicata seconda differenza tra classi e strutture.

Cita lo standard (§11.2.2 da C++98 a C++11):

In assenza di un specificatore di accessoPer una classe di base, il pubblico è assunto quando viene dichiarata la classe derivata struttura e si presuppone private quando viene dichiarata la classe classe.

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

Membro di una classe definita con la parola chiave classe Sono privato Per impostazione predefinita.Membri di una classe definiti con le parole chiave struttura O unioneSono pubblico per impostazione predefinita.

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

Altri suggerimenti

Citando Domande frequenti sul C++,

7.8] Qual è la differenza tra le parole chiave e la classe?

I membri e le classi di base di una struttura sono pubblici per impostazione predefinita, mentre in classe sono inadempienti verso privati.Nota:Dovresti rendere esplicitamente pubblici, private o protette le tue lezioni di base, piuttosto che fare affidamento sulle impostazioni predefinite.

Struttura e classe sono altrimenti funzionalmente equivalenti.

Ok, abbastanza di quel discorso techno pulito cigolante.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 pochissimo in termini di incapsulamento o funzionalità.Una classe sembra 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 la maggior parte delle persone ha già, probabilmente dovresti usare la parola chiave struct se hai una classe che ha pochissimi metodi e ha dati pubblici (tali cose esistono in sistemi ben progettati!), Ma altrimenti dovresti probabilmente usare la classe parola chiave.

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

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

Essere pubblici per impostazione predefinita è generalmente considerato una cattiva idea quando si adotta un approccio orientato agli oggetti, quindi nel creare una forma di C che sia nativamente favorevole all'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 di struct in modo che i suoi membri fossero privati ​​​​per impostazione predefinita, avrebbe interrotto la compatibilità (non è più così spesso vero poiché gli standard divergevano, ma tutti i programmi C validi erano anche programmi C++ validi, il che ha avuto un grande effetto nel dare un punto d'appoggio al C++).

Quindi una nuova parola chiave, class è stato introdotto per essere esattamente come una struttura, ma privata per impostazione predefinita.

Se il C++ fosse nato da zero, senza cronologia, probabilmente avrebbe solo una di queste parole chiave.Inoltre, probabilmente non avrebbe avuto l'impatto che ha avuto.

In generale, le persone tenderanno a usare struct quando fanno qualcosa di simile al modo in cui vengono usate le struct in C;membri pubblici, nessun costruttore (a patto che non sia in un'unione, you Potere avere costruttori nelle strutture, proprio come con le classi, ma le persone tendono a non farlo), nessun metodo virtuale, ecc.Dato che i linguaggi servono tanto per comunicare con le persone che leggono il codice quanto per istruire le macchine (altrimenti resteremmo con codici operativi assembly e VM grezzi), è una buona idea attenersi a quello.

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

Secondo Stroustrup nel Linguaggio di programmazione C++:

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

Funzionalmente non c'è altra differenza che quella pubblica/privata

STRUCT è un tipo di tipo di dati astratto che divide una determinata porzione 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 parola per parola.(cioè.Ottenere un puntatore alla struttura, utilizzare la macro DIMENSIONE per calcolare il numero di byte da copiare, quindi spostare i dati dentro o fuori la struttura.)

Le classi sono un diverso tipo di dati astratti che tentano di garantire l'occultamento delle informazioni.Internamente, possono esserci una varietà di macchinazioni, metodi, variabili temporanee, variabili di stato.eccetera.vengono 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 queste sono semplicemente astrazioni.È perfettamente possibile creare strutture che assomigliano molto alle classi e classi che assomigliano molto alle strutture.In effetti, i primi compilatori C++ erano semplicemente precompilatori che traducevano il codice C++ in C.Pertanto queste astrazioni rappresentano un vantaggio per il pensiero logico, non necessariamente una risorsa per il computer stesso.

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

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 a compilare 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 struttura da una classe/struttura, lo specificatore di accesso predefinito per una classe/struttura base è pubblico.E quando si deriva una classe, l'identificatore di accesso predefinito è private.

Ad esempio, il programma 3 non riesce a compilare 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;
}

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

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

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

Il vecchio codice ha strutture, il codice è stato ripulito e queste sono state modificate 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 ciò interromperebbe il vecchio codice legacy è che se nel vecchio codice da qualche parte la struttura fosse cancellata utilizzando memfill per cancellare tutto a zero, questo calpesterebbe anche i dati del puntatore extra.

  1. I membri di una struttura sono pubblici per impostazione predefinita, i membri di classe sono privati ​​per impostazione predefinita.
  2. L'ereditarietà predefinita per la struttura 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.

Un'altra differenza principale riguarda i 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. Membro di una classe definita con la parola chiave class Sono private per impostazione predefinita.Membri di una classe definita con le parole chiave struct (O union) Sono public per impostazione predefinita.

  2. In assenza di uno specificatore di accesso per una classe base, public si presuppone quando il derivato viene dichiarata la classe struct E private viene assunto quando la classe viene dichiarata class.

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

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

Tieni inoltre presente che lo standard C++ ti consente di dichiarare in avanti un tipo come a struct, quindi utilizzare class quando si dichiara la tipologia e viceversa.Anche, std::is_class<Y>::value È true poiché Y è a struct e un class, ma è false per un enum class.

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.

E' solo una convenzione.È possibile creare strutture per contenere dati semplici ma successivamente evolvere il tempo con l'aggiunta di funzioni membro e costruttori.D'altronde è insolito vedere qualcosa di diverso dal pubblico:accesso in una struttura.

ISOIEC 14882-2003

9 classi

§3

Una struttura è una classe definita con il chiave di classe struct;I suoi membri e le classi di base (clausola 10) sono pubblici per impostazione predefinita (clausola 11).

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

Ciò che potrebbe essere interessante notare (soprattutto perché è probabile che chi richiede la richiesta utilizzi MSVC++ poiché menziona C++ "non gestito") è che Visual C++ si lamenta in determinate circostanze se una classe viene dichiarata con class e poi definito con struct (o forse il contrario), anche se lo standard afferma che è perfettamente legale.

  • .Nelle classi tutti i membri per impostazione predefinita sono privati ​​ma nelle strutture 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 crea default se non lo fornisci.

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

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

    In breve, la convenzione è quella di utilizzare la struttura quando lo scopo è quello di raggruppare i dati e utilizzare le classi quando richiediamo astrazione dei dati e, forse eredità.

    Nelle strutture e le classi C ++ vengono passate per valore, a meno che non si riferiscano esplicitamente.In altre lingue le classi e le strutture possono avere una semantica distinta - cioè.Gli oggetti (istanze di classi) possono essere approvati per riferimento e le strutture possono essere approvate per valore.Nota:Ci sono commenti associati a questa domanda.Vedi la pagina di discussione da aggiungere alla conversazione.

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

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

La differenza tra class E struct è una differenza tra parole chiave, non tra tipi di dati.Questi due

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

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

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

La classe ha significato 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 che limiti il ​​fatto che sia necessario fare riferimento al membro della classe.

Quando sviluppi un progetto di grandi dimensioni con tonnellate di persone senza classe, potresti finalmente ottenere un codice accoppiato complicato perché tutti utilizzano le funzioni e i dati che desiderano.La classe fornisce controlli di autorizzazione e caratteristiche inerenti per migliorare il disaccoppiamento e il riutilizzo dei codici.

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

A proposito, quando una struttura alloca una piccola quantità di memoria e include diverse variabili, le variabili di tipo 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 fanno riferimento a un puntatore anch'esso incorporato nel punto in cui è allocata la struttura.

Potresti considerarlo come guida su quando utilizzare struct o class, https://msdn.microsoft.com/en-us/library/ms229017%28v=vs.110%29.aspx .

√ Considera la definizione di una struttura anziché una classe se le istanze del tipo sono piccole e comunemente di breve durata o sono comunemente incorporate in altri oggetti.

X Evita 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, doppio, ecc.).

Ha una dimensione dell'istanza sotto 16 byte.

È immutabile.

Non dovrà essere inscatolato frequentemente.

La differenza tra struttura E classe parole chiave in C++ è che, quando non esiste un specificatore specifico su un particolare tipo di dati composito, per impostazione predefinita struttura O unione è la parola chiave pubblica che considera semplicemente l'occultamento dei dati, ma classe è la parola chiave privata che considera l'occultamento di codici o dati di programma.Alcuni programmatori usano sempre struttura per dati e classe per amore del codice.Per ulteriori informazioni contattare altre fonti.

Di tutti questi fattori, si può concludere che il concetto di Classe è altamente adatto a rappresentare oggetti del mondo reale piuttosto che "Strutture". Soprattutto perché i concetti OOP utilizzati in classe sono altamente pratici nello spiegare gli scenari del 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, è ridicolo. Ma in una classe l'ereditarietà predefinita è privata, il che è più realistico.

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

La differenza principale tra la parola chiave struttura e classe in oops è che nessuna dichiarazione di membro pubblico e privato presente nella struttura e il membro dati e la funzione membro possono essere definiti come pubblici, privati ​​e protetti.

Ho trovato un'altra differenza.se non definisci 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 in cui non abbiamo davvero bisogno di un costruttore, struct è una scelta migliore (suggerimento per le prestazioni).e scusa per il mio pessimo inglese.

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 quello 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. mioOggettoClasse1
  2. mioOggettoClasse2

e punterà alla stessa posizione di memoria.
Fondamentalmente assegna la stessa posizione di memoria a un'altra variabile dello stesso tipo.

Pertanto, se eventuali modifiche apportate a uno qualsiasi degli oggetti di tipo MyClass avranno effetto su un altro
poiché entrambi puntano alla stessa posizione di memoria.

"_myclassObject1.DataMember = 10;" A questa riga entrambi i membri dei dati dell'oggetto conterranno il valore di 10.
"_myclassObject2.DataMember = 20;" In questa riga, entrambi i dati dei dati dell'oggetto contiene il valore di 20.
Infine, stiamo accedendo ai dati 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 di cui sopra,
istanziando l'oggetto di tipo MyStructure utilizzando l'operatore new e
memorizzazione dell'indirizzo nella variabile _myStructObject di tipo MyStructure e
assegnando 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 assegnandovi _myStructObject1.
Qui il compilatore .NET C# crea un'altra copia dell'oggetto _myStructureObject1 e
assegna quella 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é diciamo che le strutture sono tipi di valore.

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

Come lo diciamo?
E qual è la ragione di ciò?
La risposta è Classi.

Può essere astratto, sigillato, statico e parziale e non può essere Privato, Protetto e protetto internamente.

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

-> un'altra cosa utile che trovo in class vs struct è che durante l'implementazione dei file in un programma se vuoi eseguire alcune operazioni di una struct ancora e ancora su ogni nuovo insieme di operazioni devi creare una funzione separata e devi passare l'oggetto della struct dopo averlo letto dal file in modo da poter effettuare alcune operazioni su di esso.mentre in classe crei una funzione che esegue alcune operazioni sui dati necessari ogni volta... è facile, devi solo leggere l'oggetto dal file e chiamare la funzione..

Ma dipende dal programmatore quale modalità trova adatta... secondo me preferisco sempre la lezione solo perché supporta gli OOP ed è per questo che è implementata in quasi tutti i linguaggi ed è la caratteristica meravigliosa della programmazione di tutti i tempi ;- )

E sì, la differenza più indimenticabile che ho dimenticato di menzionare è che la classe supporta l'occultamento dei dati e supporta anche le operazioni eseguite su tipi di dati incorporati mentre struct no!

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


Vedo un'altra differenza tra strutture e classi che ha 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.classe.Lo vedo con Visual Studio.

Ci sono 3 differenze fondamentali tra struttura e classe

1a memoria è riservata per la struttura nella memoria dello stack (che è vicina al linguaggio di programmazione), sia che per la classe nella memoria dello stack sia riservata solo la reffrenza e la memoria effettiva sia riservata nella memoria heap.

2° - Per impostazione predefinita, la struttura viene trattata come pubblica se la classe viene trattata come privata.

3°- non possiamo riutilizzare il codice nella struttura ma in classe possiamo riutilizzare lo stesso codice in molte volte chiamato inhertence

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top