Wanneer moet je een klasse versus een struct gebruiken in C++?

In welke scenario’s is het beter om een structte gebruiken in plaats van een classin C++?


Antwoord 1, autoriteit 100%

De verschillen tussen een classen een structin C++ zijn:

  • struct-leden en basisklassen/structs zijn standaard public.
  • classleden en basisklassen/struts zijn standaard private.

Zowel klassen als structs kunnen een combinatie hebben van public, protecteden privateleden, kunnen overerving gebruiken en kunnen lidfuncties hebben.

Ik zou je aanraden:

  • gebruik structvoor gewone-oude-gegevensstructuren zonder klasse-achtige functies;
  • gebruik classwanneer u gebruikmaakt van functies zoals privateof protectedleden, niet-standaard constructors en operators, enz.

Antwoord 2, autoriteit 28%

Zoals iedereen opmerkt, zijn er eigenlijk maar twee echte taalverschillen:

  • structis standaard ingesteld op openbare toegang en classis standaard ingesteld op privétoegang.
  • Tijdens het erven, wordt structstandaard ingesteld op publicovererving en classstandaard op privateovererving. (Ironisch genoeg, zoals met zoveel dingen in C++, is de standaard achteruit: publicovererving is verreweg de meest voorkomende keuze, maar mensen verklaren zelden structs alleen om op te besparen door het trefwoord “public” te typen.

Maar het echte verschil in de praktijk is tussen een class/ structdie een constructeur / destructor verklaart en een die dat niet doet. Er zijn bepaalde garanties voor een “PLAST-Old-Data” POD-type, dat niet langer van toepassing is als u de constructie van de klas overneemt. Om dit onderscheid duidelijk te houden, gebruiken veel mensen opzettelijk alleen structs voor pod-typen en, als ze überhaupt alle methoden zullen toevoegen, classes. Het verschil tussen de twee onderstaande fragmenten is anderszins zinloos:

class X
{
  public:
  // ...
};
struct X
{
  // ...
};

(Overigens, hier is een draad met een aantal goede uitleg over wat “pod type” eigenlijk betekent: Wat zijn pod-types in C++? )


3, Autoriteit 24%

Er zijn veel misvattingen in de bestaande antwoorden.

zowel classen structdeclareren een klasse.

Ja, misschien moet u uw toegangsbewerkwoorden in de klasse-definitie opnieuw rangschikken, afhankelijk van het trefwoord waarop u de klasse hebt aangemerkt.

Maar niet-syntaxis, de alleen reden om de een over de andere te kiezen, is conventie / stijl / voorkeur.

Sommige mensen houden ervan om bij de structtrefwoord voor klassen zonder ledenfuncties, omdat de resulterende definitie “eruit ziet” een eenvoudige structuur van c.

Evenzo gebruiken sommige mensen graag de classtrefwoord voor klassen met lidfuncties en privategegevens, omdat het “Klasse” erop ziet en erom uitkijkt uit Hun favoriete boek op objectgeoriënteerde programmering.

De realiteit is dat dit volledig aan jou en je team ligt, en het zal letterlijk geen enkel verschil maken voor je programma.

De volgende twee klassen zijn in alle opzichten absoluut gelijkwaardig, behalve hun naam:

struct Foo
{
   int x;
};
class Bar
{
public:
   int x;
};

U kunt zelfs van trefwoord wisselen bij het opnieuw declareren:

class Foo;
struct Bar;

(hoewel dit de Visual Studio-builds verbreektvanwege niet-conformiteit, zodat de compiler een waarschuwing geeft wanneer u dit doet dit.)

en de volgende uitdrukkingen evalueren beide naar waar:

std::is_class<Foo>::value
std::is_class<Bar>::value

Houd er echter rekening mee dat u de trefwoorden niet kunt wijzigen wanneer u herdefinieert; dit is alleen omdat (volgens de één-definitieregel) dubbele klassedefinities tussen vertaaleenheden “uit dezelfde reeks tokens moeten bestaan”. Dit betekent dat je const int member;niet eens kunt uitwisselen met int const member;, en heeft niets te maken met de semantiek van classof struct.


Antwoord 4, autoriteit 6%

De enige keer dat ik een struct gebruik in plaats van een klasse, is wanneer ik een functor declareer vlak voordat ik deze in een functieaanroep gebruik en de syntaxis voor de duidelijkheid wil minimaliseren. bijv.:

struct Compare { bool operator() { ... } };
std::sort(collection.begin(), collection.end(), Compare()); 

Antwoord 5, autoriteit 4%

Vanaf de C++ FAQ Lite :

De leden en de basisklassen van een struct zijn standaard openbaar, terwijl ze in de klas standaard zijn. Opmerking: u moet uw basisklassen expliciet openbaar, privé of beschermd maken in plaats van op de standaardinstellingen te vertrouwen.

Struct en klasse zijn anderszins functioneel equivalent.

Ok, genoeg van die squeaky clean techno talk. Emotioneel maken de meeste ontwikkelaars een sterk onderscheid tussen een klasse en een struct. Een struct voelt zich eenvoudig als een open stapel stukjes met heel weinig in de inkapseling of functionaliteit. Een klasse voelt als een levend en verantwoordelijk lid van de samenleving met intelligente diensten, een sterke inkapselingsbarrière en een goed gedefinieerde interface. Omdat dat de connotatie is, hebben de meeste mensen al, dan moet je het struct-trefwoord waarschijnlijk gebruiken als je een klasse hebt die heel weinig methoden heeft en openbare gegevens heeft (dergelijke dingen bestaan ​​in goed ontworpen systemen!), Maar anders zou je de klasse waarschijnlijk moeten gebruiken sleutelwoord.


6, Autoriteit 2%

Eén plaats waar een structuur nuttig is voor mij is wanneer ik een systeem heb dat vaste-formaatberichten ontvangt (over zeg, een seriële poort) van een ander systeem. U kunt de stroom van bytes in een structuur werpen die uw velden definieert en vervolgens gemakkelijk toegang krijgen tot de velden.

typedef struct
{
    int messageId;
    int messageCounter;
    int messageData;
} tMessageType;
void processMessage(unsigned char *rawMessage)
{
    tMessageType *messageFields = (tMessageType *)rawMessage;
    printf("MessageId is %d\n", messageFields->messageId);
}

Natuurlijk is dit hetzelfde als wat je zou doen in C, maar ik vind dat de overhead van het moeten decoderen van het bericht in een klasse meestal niet de moeite waard is.


Antwoord 7, autoriteit 2%

Je kunt “struct” in C++ gebruiken als je een bibliotheek schrijft waarvan de interne inhoud C++ is, maar de API kan worden aangeroepen door C- of C++-code. U maakt eenvoudig een enkele header die structs en globale API-functies bevat die u blootstelt aan zowel C- als C++-code als volgt:

// C access Header to a C++ library
#ifdef __cpp
extern "C" {
#endif
// Put your C struct's here
struct foo
{
    ...
};
// NOTE: the typedef is used because C does not automatically generate
// a typedef with the same name as a struct like C++.
typedef struct foo foo;
// Put your C API functions here
void bar(foo *fun);
#ifdef __cpp
}
#endif

Dan kun je een functiebalk() in een C++-bestand schrijven met behulp van C++-code en het aanroepbaar maken vanuit C en de twee werelden kunnen gegevens delen via de gedeclareerde structs. Er zijn natuurlijk andere kanttekeningen bij het mixen van C en C++, maar dit is een vereenvoudigd voorbeeld.


Antwoord 8, autoriteit 2%

Zoals iedereen zegt, is het enige echte verschil de standaardtoegang. Maar ik gebruik struct vooral als ik geen enkele vorm van inkapseling wil met een eenvoudige gegevensklasse, zelfs als ik een aantal hulpmethoden implementeer. Als ik bijvoorbeeld zoiets als dit nodig heb:

struct myvec {
    int x;
    int y;
    int z;
    int length() {return x+y+z;}
};

Antwoord 9

Structs (POD’s, meer in het algemeen) zijn handig wanneer u een C-compatibele interface levert met een C++-implementatie, aangezien ze over taalgrenzen en linkerformaten kunnen worden overgedragen.

Als u zich daar geen zorgen over maakt, dan veronderstel ik dat het gebruik van de “struct” in plaats van “class” een goede intentie is (zoals @ZeroSignal hierboven zei). Structuren hebben ook een meer voorspelbare kopieersemantiek, dus ze zijn handig voor gegevens die u naar externe media wilt schrijven of over de draad wilt verzenden.

Structs zijn ook handig voor verschillende metaprogrammeertaken, zoals sjablonen voor eigenschappen die slechts een aantal afhankelijke typedefs blootleggen:

template <typename T> struct type_traits {
  typedef T type;
  typedef T::iterator_type iterator_type;
  ...
};

…Maar dat is eigenlijk gewoon profiteren van het feit dat het standaardbeveiligingsniveau van struct openbaar is…


Antwoord 10

Voor C++ is er niet veel verschil tussen structs en klassen. Het belangrijkste functionele verschil is dat leden van een struc standaard openbaar zijn, terwijl ze standaard privé zijn in klassen. Anders zijn ze wat de taal betreft gelijkwaardig.

Dat gezegd hebbende, heb ik de neiging om structs in C++ te gebruiken zoals ik in C# doe, vergelijkbaar met wat Brian heeft gezegd. Structuren zijn eenvoudige gegevenscontainers, terwijl klassen worden gebruikt voor objecten die niet alleen op de gegevens moeten reageren, maar er ook aan moeten vasthouden.


Antwoord 11

Om mijn eigen vraag te beantwoorden (schaamteloos): Zoals eerder vermeld, zijn toegangsprivileges het enige verschil tussen hen in C++.

Ik heb de neiging om alleen een struct voor data-opslag te gebruiken. Ik zal het toestaan ​​om een ​​paar helperfuncties te krijgen als het werkt met de gegevens eenvoudiger. Zodra de gegevens echter flow-besturing vereist (dwz Getters / Setters die een interne toestand onderhouden of beschermen) of beginnen met een grote functionaliteit (in principe meer object-achtige), wordt het ‘geüpgraded’ naar een klasse om de intentie beter te communiceren.


12

Ze zijn vrijwel hetzelfde. Dankzij de magie van C++ kan een structuur functies bevatten, erfenis gebruiken, gemaakt met behulp van “nieuw” enzovoort, net als een klasse

Het enige functionele verschil is dat een klasse begint met privétoegangsrechten, terwijl een struct met publiek begint. Dit is de onderhoud van de achterwaartse compatibiliteit met c.

In de praktijk heb ik altijd gebruikt als gegevenshouders en klassen als objecten.


13

Een voordeel van structOver classis dat het één regel code opslaat, indien het hechten aan “eerste openbare leden, dan privé”. In dit licht vind ik het trefwoord classnutteloos.

Hier is een andere reden voor het gebruik van alleen structen nooit class. Sommige codestijlrichtlijnen voor C++ suggereren met behulp van kleine letters voor functie-macro’s, waarbij de reden is dat wanneer de macro wordt geconverteerd naar een inline-functie, de naam niet moet worden gewijzigd. Hier ook. Je hebt je mooie C-stijl Struct en op een dag, je komt erachter dat je een constructeur moet toevoegen, of een gemaksmethode. Verandert u het met een class? Overal?

Distinguishing tussen structS en classES is gewoon te veel gedoe, in de manier waarop we moeten doen – programmeren. Zoals zoveel van C++’s problemen, ontstaat het uit het sterke verlangen naar achterwaartse compatibiliteit.


14

Zoals anderen hebben opgemerkt

  • beide zijn gelijkwaardig, afgezien van de standaardzichtbaarheid
  • er kunnen redenen zijn om om welke reden dan ook gedwongen te worden om het een of het ander te gebruiken

Er is een duidelijke aanbeveling over wanneer je welke moet gebruiken van Stroustrup/Sutter:

Gebruik klasse als de klasse een invariant heeft; gebruik struc als de gegevensleden onafhankelijk kunnen variëren

Houd er echter rekening mee dat het niet verstandig is om declaratie door te sturen. als een klasse (class X;) en definieer deze als struct (struct X { ... }).
Het kan werken op sommige linkers (bijv. g++) en kan mislukken op andere (bijv. MSVC), dus u bevindt zich in de hel van de ontwikkelaar.


Antwoord 15

Klasse.

Lesgroepleden zijn standaard privé.

class test_one {
    int main_one();
};

Is gelijk aan

class test_one {
  private:
    int main_one();
};

Dus als je het probeert

int two = one.main_one();

We krijgen een foutmelding: main_one is privateomdat het niet toegankelijk is. Wij kunnen
los het op door het te initialiseren door het op te geven dat het een openbare dwz is

class test_one {
  public:
    int main_one();
};

Struct.

Een struct is een klasse waarin leden standaard openbaar zijn.

struct test_one {
    int main_one;
};

betekent main_oneis privé, dwz

class test_one {
  public:
    int main_one;
};

I GEBRUIKEN UITSTEKENS VOOR DATASTRUCTUREN WAAR DE LEDEN OM ENIGE VALUEK KUNNEN, HET IS
gemakkelijker die manier.


16

ze zijn hetzelfde met verschillende standaardinstellingen (privé standaard voor classen standaard openbaar voor struct), dus in theorie zijn ze volledig uitwisselbaar.

dus als ik alleen wat informatie wil verpakken om me te verplaatsen, gebruik ik een struct, zelfs als ik daar een paar methoden plaats (maar niet veel). Als het een grotendeels ondoorzichtig ding is, waarbij het belangrijkste gebruik via methoden zou zijn en niet rechtstreeks naar de gegevensleden, gebruik ik een volledige klasse.


Antwoord 17

Structs hebben standaard openbare toegang en klassen hebben standaard privétoegang.

Persoonlijk gebruik ik structs voor Data Transfer Objects of als Value Objects. Bij gebruik als zodanig verklaar ik alle leden als const om wijziging door andere code te voorkomen.


Antwoord 18

Technisch gezien zijn beide hetzelfde in C++ – het is bijvoorbeeld mogelijk dat een struct overbelaste operators heeft, enz.

Echter:

Ik gebruik structs als ik informatie van meerdere typen tegelijk wil doorgeven
Ik gebruik klassen wanneer ik te maken heb met een “functioneel” object.

Hopelijk helpt het.

#include <string>
#include <map>
using namespace std;
struct student
{
    int age;
    string name;
    map<string, int> grades
};
class ClassRoom
{
    typedef map<string, student> student_map;
  public :
    student getStudentByName(string name) const 
    { student_map::const_iterator m_it = students.find(name); return m_it->second; }
  private :
    student_map students;
};

Ik geef bijvoorbeeld een struct-student terug in de get…()-methoden hier – veel plezier.


19

I GEBRUIKEN STRUCTIONS wanneer ik POD-type of FUNCTOR moet maken.


20

Alle klassenleden zijn standaard privé en alle struct-leden zijn standaard openbaar.
Klasse is standaard privébases en structuren heeft standaard openbare bases. Struct in het geval van C kan geen ledenfuncties hebben waar we in het geval van C++ kunnen ledenfuncties hebben toegevoegd aan de struct. Anders dan deze verschillen, ik vind niets verrassends over hen.


21

Gewoon om dit te adresseren vanuit een C++ 20-standaard perspectief (werken van N4860 ) …

A Klasse is een type. De trefwoorden “class” en “struct” (en “union“) zijn – in de C++ Grammatica – Class-Key S en de enige functionele betekenis van de keuze van classof structis:

De -toets Bepaalt of … toegang is openbaar of privé standaard (11.9).

Data-lid standaard toegankelijkheid

DAT DE classTrefwoord Trefwoord resulteert in particuliere leden, en `Struct-trefwoord resulteert in public-by-standaard leden, worden gedocumenteerd door de voorbeelden in 11.9.1:

Klasse x {
int een; // X::a is standaard privé: gebruikte klasse

…vs…

structuur S {
int een; // S::a is standaard openbaar: struct gebruikt

Basisklasse standaard toegankelijkheid

1.9 zegt ook:

Bij afwezigheid van een access-specificatievoor een basisklasse, wordt publicaangenomen wanneer de afgeleide klasse wordt gedefinieerd met de class-keystructen privatewordt aangenomen wanneer de klasse is gedefinieerd met de class-keyclass.

Omstandigheden waarin consistent gebruik van struct of klasse vereist is…

Er is een vereiste:

In een herdeclaratie, gedeeltelijke specialisatie, expliciete specialisatie of expliciete concretisering van een klassensjabloon, moet de class-keyin natura overeenkomen met de originele verklaring van het klassensjabloon (9.2.8.3).

…in elke elaborated-type-specifiermoet het trefwoord enumworden gebruikt om te verwijzen naar een opsomming (9.7.1), de unionclass-keywordt gebruikt om te verwijzen naar een union(11.5), en ofwel de classof structklasse-sleutelzal zijn
gebruikt om te verwijzen naar een niet-vakbondsklasse (11.1).

Het volgende voorbeeld (van wanneer consistentie nietvereist is) wordt gegeven:

struct S { } s;
klasse S* p = & s; // OK

Toch kunnen sommige samenstellers hiervoor waarschuwen.


Interessant is dat hoewel de typen die u maakt met struct, classen unionallemaal “klassen” worden genoemd, we…

Een standaard-layout structis een standaard lay-outklasse gedefinieerd met de class-keystructof de class-keyclass.

…dus in Standardees, wanneer er sprake is van een standaard-layout struct, wordt “struct” gebruikt om “geen vakbond” aan te duiden.

Ik ben benieuwd of er een soortgelijk gebruik van “struct” in andere terminologie is, maar het is een te grote klus om de Standaard uitputtend te doorzoeken. Opmerkingen hierover zijn welkom.


Antwoord 22

Ik gebruik struct alleen als ik bepaalde gegevens moet bewaren zonder daaraan gekoppelde lidfuncties (om met de lidgegevens te werken) en om rechtstreeks toegang te krijgen tot de gegevensvariabelen.

Bijvoorbeeld: gegevens lezen/schrijven uit bestanden en socketstreams enz. Functieargumenten doorgeven in een structuur waar de functieargumenten te veel zijn en de functiesyntaxis te lang lijkt.

Technisch gezien is er geen groot verschil tussen klasse en structuur, behalve standaardtoegankelijkheid.
Bovendien hangt het af van de programmeerstijl hoe je het gebruikt.


Antwoord 23

Other episodes