Question Quand devriez-vous utiliser une classe vs une structure en C ++?


Dans quels scénarios est-il préférable d'utiliser un struct vs un class en C ++?


721
2017-09-10 16:29


origine


Réponses:


Différences entre un class et un struct en C ++ sont que les structures ont par défaut public les membres et les bases et les classes ont par défaut private membres et bases. Les deux classes et structures peuvent avoir un mélange de public, protected et private membres, peuvent utiliser l'héritage et peuvent avoir des fonctions membres.

Je recommanderais d'utiliser des structures comme des structures de plain-old-data sans aucune fonctionnalité de classe, et d'utiliser des classes comme structures de données agrégées avec private données et fonctions membres.


620
2017-09-10 16:35



Comme tout le monde le fait remarquer, il n'y a vraiment que deux différences linguistiques:

  • struct par défaut à l'accès du public et class par défaut à l'accès privé.
  • En héritant, struct par défaut public héritage et class par défaut private héritage. (Ironiquement, comme avec beaucoup de choses en C ++, la valeur par défaut est en arrière: public l'héritage est de loin le choix le plus commun, mais les gens déclarent rarement structs juste pour économiser en tapant le "public" mot-clé.

Mais la vraie différence dans la pratique est entre un class/struct cela déclare un constructeur / destructeur et un qui ne le fait pas. Il y a certaines garanties à un type de POD "plaine ancienne", qui ne s'applique plus une fois que vous avez repris la construction de la classe. Pour garder cette distinction claire, beaucoup de gens utilisent délibérément seulement structs pour les types de POD, et, s'ils vont ajouter des méthodes, utilisez classes. La différence entre les deux fragments ci-dessous est autrement insignifiante:

class X
{
  public:

  // ...
};

struct X
{
  // ...
};

(Incidemment, voici un fil avec quelques bonnes explications sur ce que "type POD" signifie réellement: Quels sont les types de POD en C ++?)


173
2017-07-28 04:02



Il y a beaucoup d'idées fausses dans les réponses existantes.

Tous les deux class et struct déclarer une classe.

Oui, vous devrez peut-être réorganiser vos mots-clés de modification d'accès dans la définition de classe, en fonction du mot-clé que vous avez utilisé pour déclarer la classe.

Mais, au-delà de la syntaxe, le seulement la raison de choisir l'une par rapport à l'autre est la convention / le style / la préférence.

Certaines personnes aiment coller avec le struct mot-clé pour les classes sans fonctions membres, car la définition résultante "ressemble" à une structure simple de C.

De même, certaines personnes aiment utiliser le class mot-clé pour les classes avec des fonctions membres et private données, parce qu'il dit "classe" sur lui et ressemble donc à des exemples de leur livre préféré sur la programmation orientée objet.

La réalité est que cela dépend entièrement de vous et de votre équipe, et cela ne fera littéralement aucune différence pour votre programme.

Les deux classes suivantes sont absolument équivalentes à tous égards sauf leur nom:

struct Foo
{
   int x;
};

class Bar
{
public:
   int x;
};

Vous pouvez même changer de mots clés lors de la redéclaration:

class Foo;
struct Bar;

(bien que certains compilateurs émettent un avertissement lorsque vous faites cela, en supposant que vous n'avez probablement pas intention faire quelque chose de si confus et que vous devriez donc être invité à vérifier votre code.)

et les expressions suivantes évaluent toutes deux à vrai:

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

Notez cependant que vous ne pouvez pas changer les mots-clés lorsque redéfinir; c'est seulement parce que (selon la règle de définition unique) les définitions de classe en double à travers les unités de traduction doivent "consistent en la même séquence de jetons". Cela signifie que vous ne pouvez même pas échanger const int member; avec int const member;, et n'a rien à voir avec la sémantique de class ou struct.


90
2018-04-28 14:17



La seule fois où j'utilise une structure au lieu d'une classe, c'est quand on déclare un foncteur juste avant de l'utiliser dans un appel de fonction et que l'on veut minimiser la syntaxe par souci de clarté. par exemple.:

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

50
2017-09-10 18:08



Du C ++ FAQ Lite:

Les membres et les classes de base d'une structure sont publics par défaut, tandis qu'en classe, ils sont privés par défaut. Remarque: vous devez rendre vos classes de base explicitement publiques, privées ou protégées, plutôt que de vous fier aux valeurs par défaut.

struct et class sont par ailleurs fonctionnellement équivalents.

OK, assez de cette conversation techno grincheuse. Emotionnellement, la plupart des développeurs font une forte distinction entre une classe et une structure. Une structure ressemble simplement à un tas ouvert de bits avec très peu d'encapsulation ou de fonctionnalité. Une classe se sent comme un membre vivant et responsable de la société avec des services intelligents, une forte barrière d'encapsulation et une interface bien définie. Puisque c'est la connotation que la plupart des gens ont déjà, vous devriez probablement utiliser le mot-clé struct si vous avez une classe qui a très peu de méthodes et des données publiques (ces choses existent dans des systèmes bien conçus!), Sinon vous devriez utiliser la classe mot-clé.


30
2017-07-28 04:07



Un endroit où une structure a été utile pour moi est quand j'ai un système qui reçoit des messages au format fixe (par exemple, un port série) d'un autre système. Vous pouvez convertir le flux d'octets en une structure qui définit vos champs, puis accéder facilement aux champs.

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

Évidemment, c'est la même chose que dans C, mais je trouve que le fait de devoir décoder le message dans une classe ne vaut généralement pas le coup.


19
2017-09-10 16:43



Vous pouvez utiliser "struct" en C ++ si vous écrivez une bibliothèque dont les internes sont en C ++ mais l'API peut être appelée par du code C ou C ++. Vous créez simplement un en-tête unique contenant des structures et des fonctions API globales que vous exposez au code C et au code C ++ comme suit:

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

Ensuite, vous pouvez écrire une fonction bar () dans un fichier C ++ en utilisant du code C ++ et le rendre appelable de C et les deux mondes peuvent partager des données à travers les structures déclarées. Il y a bien sûr d'autres mises en garde quand on mélange C et C ++, mais c'est un exemple simplifié.


15
2017-10-27 01:50



Structures (PODs, plus généralement) sont pratiques lorsque vous fournissez une interface C-compatible avec une implémentation C ++, car ils sont portables à travers les frontières de la langue et les formats de liens.

Si cela ne vous concerne pas, alors je suppose que l'utilisation de la "structure" au lieu de "classe" est un bon communicateur d'intention (comme l'a dit @ZeroSignal ci-dessus). Les structures ont également une sémantique de copie plus prévisible, elles sont donc utiles pour les données que vous avez l'intention d'écrire sur un support externe ou d'envoyer à travers le réseau.

Les structures sont également utiles pour diverses tâches de métaprogrammation, comme les modèles de traits qui exposent juste un tas de typedefs dépendants:

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

... Mais c'est vraiment profiter du niveau de protection par défaut de struct étant public ...


9
2017-09-10 17:46