web-dev-qa-db-fra.com

Quelles sont les différences entre struct et class en C ++?

Cette question était déjà posée dans le contexte de C # /. Net .

Maintenant, j'aimerais apprendre les différences entre une structure et une classe en C++. Veuillez discuter des différences techniques ainsi que des raisons de choisir l’un ou l’autre dans la conception OO.

Je vais commencer par une différence évidente:

  • Si vous ne spécifiez pas public: ou private:, les membres d'une structure sont publics par défaut. les membres d'une classe sont privés par défaut.

Je suis sûr qu'il existe d'autres différences dans les angles obscurs de la spécification C++.

420
palm3D

Vous oubliez la 2e différence délicate entre les classes et les structures.

La norme (§11.2.2 en C++ 98 à C++ 11):

En l'absence d'un spécificateur d'accès pour une classe de base, public est supposé lorsque la classe dérivée est déclarée struct et privé est supposé lorsque la classe est déclarée classe .

Et juste pour être complet, la différence plus largement connue entre class et struct est définie dans (11.2):

Membre d'une classe définie avec le mot clé , la classe est privée par défaut. Les membres d'une classe définie avec les mots-clés struct ou union sont public par défaut.

Différence supplémentaire: le mot clé class peut être utilisé pour déclarer des paramètres de modèle, alors que le mot clé struct ne peut pas être utilisé de la sorte.

453
Assaf Lavie

Citant La FAQ C++ ,

[7.8] Quelle est la différence entre les mots clés struct et class?

Les membres et les classes de base d'une structure sont publics par défaut, alors qu'en classe, ils sont par défaut privés. 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 ce discours techno propre et grinçant. Émotionnellement, la plupart des développeurs font une distinction forte entre une classe et une structure. Une structure ressemble simplement à une pile de bits ouverte 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 barrière d’encapsulation forte et une interface bien définie. Comme 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 (de telles choses existent dans des systèmes bien conçus!), Sinon vous devriez probablement utiliser la classe mot-clé.

159
Robᵩ

Cela vaut la peine de rappeler les origines de C++ et sa compatibilité avec C.

C a des structures, il n’a pas de concept d’encapsulation, donc tout est public.

Etre public par défaut est généralement considéré comme une mauvaise idée lorsqu’on adopte une approche orientée objet. Il est donc préférable de créer une forme de C propice nativement à OOP (vous pouvez faire OO en C , mais cela ne vous aidera pas), ce qui était l’idée du C++ (à l’origine "C With Classes"), il est logique de rendre les membres privés par défaut.

Par contre, si Stroustrup avait changé la sémantique de struct de sorte que ses membres soient privés par défaut, la compatibilité aurait été rompue (elle n’est plus aussi souvent vraie que les normes divergentes, mais tous les programmes C valides étaient également des programmes C++ valides, qui ont eu un effet important sur l’introduction du C++).

Donc, un nouveau mot clé, class a été introduit pour ressembler exactement à une structure, mais privé par défaut.

Si C++ venait de zéro, sans historique, il n'aurait probablement qu'un seul mot clé. Cela n'aurait probablement pas eu l'impact que cela aurait eu.

En général, les gens ont tendance à utiliser struct quand ils font quelque chose comme comment les struct sont utilisées en C; membres publics, pas de constructeur (tant que ce n'est pas dans une union, vous pouvez avez des constructeurs dans les structures, comme avec les classes, mais les gens ont tendance à ne pas), pas de méthodes virtuelles, etc. Depuis les langues sont autant pour communiquer avec les lecteurs du code que pour instruire les machines (sinon nous collerions avec des opcodes Assembly et raw VM) c'est une bonne idée de s'en tenir à cela.

118
Jon Hanna

Les membres de la classe sont privés par défaut. Les membres de Struct sont publics par défaut. Outre cela, il n'y a pas d'autres différences. Voir aussi cette question .

31
Kasprzol

Selon Stroustrup dans le langage de programmation C++ :

Le style que vous utilisez dépend des circonstances et des goûts. Je préfère généralement utiliser struct pour les classes qui ont toutes les données publiques. Je pense à des classes telles que "des types pas tout à fait appropriés, juste des structures de données".

Fonctionnellement, il n'y a pas de différence autre que public/privé

28
crashmstr

STRUCT est un type de type de données abstrait qui divise un bloc de mémoire donné en fonction de la spécification de la structure. Les structures sont particulièrement utiles pour la sérialisation/désérialisation de fichiers car la structure peut souvent être écrite intégralement dans le fichier. (Par exemple, obtenez un pointeur sur la structure, utilisez la macro SIZE pour calculer le nombre d'octets à copier, puis déplacez les données dans ou hors de la structure.)

Les classes sont un type différent de type de données abstrait qui tente de garantir la dissimulation d'informations. En interne, il peut y avoir une variété de machinations, méthodes, variables temp, variables d'état. etc. qui sont tous utilisés pour présenter une API cohérente à tout code qui souhaite utiliser la classe.

En effet, les structures concernent les données, les classes concernent le code.

Cependant, vous devez comprendre que ce ne sont que des abstractions. Il est parfaitement possible de créer des structures qui ressemblent beaucoup à des classes et des classes qui ressemblent beaucoup à des structures. En fait, les premiers compilateurs C++ étaient simplement des pré-compilateurs qui traduisaient le code C++ en C. Ainsi, ces abstractions sont un avantage pour la pensée logique, pas nécessairement un atout pour l'ordinateur lui-même.

Au-delà du fait que chaque type d'abstraction est différent, Classes fournit des solutions au puzzle de nommage de code C. Comme vous ne pouvez pas exposer plus d’une fonction au même nom, les développeurs suivaient le modèle _ (). par exemple. mathlibextreme_max (). En regroupant les API dans des classes, des fonctions similaires (appelées ici "méthodes") peuvent être regroupées et protégées de la dénomination des méthodes dans les autres classes. Cela permet au programmeur de mieux organiser son code et d’augmenter sa réutilisation. En théorie au moins.

10
64BitBob

1) Les membres d'une classe sont privés par défaut et les membres de struct sont publics par défaut.

Par exemple, le programme 1 échoue lors de la compilation et le programme 2 fonctionne bien.

// 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) Lors de la dérivation d'une structure à partir d'une classe/structure, le spécificateur d'accès par défaut pour une classe/structure de base est public. Et lors de la dérivation d'une classe, le spécificateur d'accès par défaut est privé.

Par exemple, le programme 3 échoue lors de la compilation et le programme 4 fonctionne bien.

// 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;
}
10
Suraj K Thomas

La seule autre différence est l'héritage par défaut des classes et des structures, qui sont, sans surprise, privées et publiques respectivement.

8
Skizz
  1. Les membres d'une structure sont publics par défaut, les membres de la classe sont privés par défaut.
  2. L'héritage par défaut pour la structure d'une autre structure ou classe est public. L'héritage par défaut pour la classe d'une autre structure ou classe est privé.
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;
}

Ceci est sur VS2005.

4
GirishNayak

Une autre chose à noter, si vous mettiez à jour une application héritée avec des structures pour utiliser des classes, vous pourriez rencontrer le problème suivant:

Ancien code a structs, le code a été nettoyé et ceux-ci ont été modifiés en classes. Une ou deux fonctions virtuelles ont ensuite été ajoutées à la nouvelle classe mise à jour.

Lorsque les fonctions virtuelles sont dans les classes, le compilateur ajoute en interne un pointeur supplémentaire aux données de la classe pour qu'il pointe vers les fonctions.

Cela aurait pour effet de casser l'ancien code hérité si, dans l'ancien code, la structure était effacée quelque part, en utilisant memfill pour tout effacer en zéros, cela écraserait également les données de pointeur supplémentaires.

4
KPexEA

Pas dans la spécification, non. La principale différence réside dans les attentes des programmeurs qui lisent votre code en 2 ans. les structures sont souvent supposées être POD. Les structures sont également utilisées dans la métaprogrammation des modèles lorsque vous définissez un type à des fins autres que la définition d'objets.

4
MSalters
  1. Les membres d'une classe définie avec le mot clé class sont private par défaut. Les membres d'une classe définie avec les mots-clés struct (ou union) sont public par défaut.

  2. En l'absence d'un spécificateur d'accès pour une classe de base, public est utilisé lorsque la classe dérivée est déclarée struct et private est utilisée lorsque la classe est déclarée class.

  3. Vous pouvez déclarer un enum class mais pas un enum struct.

  4. Vous pouvez utiliser template<class T> mais pas template<struct T>.

Notez également que la norme C++ vous permet de déclarer un type en tant que struct, puis d'utiliser class lors de la déclaration du type et inversement. Aussi, std::is_class<Y>::value est true pour Y étant un struct et un class, mais false pour un enum class.

3
Bathsheba

Une autre différence majeure concerne les modèles. Autant que je sache, vous pouvez utiliser une classe lorsque vous définissez un modèle mais PAS une structure.

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

C'est juste une convention. Des structures peuvent être créées pour contenir des données simples, mais évoluent ensuite dans le temps avec l'ajout de fonctions membres et de constructeurs. D'autre part, il est inhabituel de voir autre chose que public: un accès dans une structure.

2
finnw

ISO IEC 14882-2003

9 classes

§3

Une structure est une classe définie avec la clé de classe struct; ses membres et ses classes de base (clause 10) sont publics par défaut (clause 11).

2
Gregory Pakosz

Voici une bonne explication: http://carcino.gen.nz/tech/cpp/struct_vs_class.php

Donc, encore une fois: en C++, une structure est identique à une classe, sauf que les membres d'une structure ont une visibilité publique par défaut, mais que les membres d'une classe ont une visibilité privée par défaut.

2
nutario
  • . Dans les classes, tous les membres par défaut sont privés, mais dans la structure, les membres sont publics par défaut.

    1. Il n'y a pas de terme comme constructeur et destructeur pour structs, mais pour compilateur de classe, crée par défaut si vous ne le fournissez pas.

    2. La taille de la structure vide est égale à 0 octet, la taille de la classe vide à 1 octet. Le type d'accès par défaut à la structure est public. Une structure doit généralement être utilisée pour regrouper des données.

    Le type d'accès par défaut à la classe est privé et le mode par défaut pour l'héritage est privé. Une classe doit être utilisée pour regrouper des données et des méthodes qui fonctionnent sur ces données.

    En bref, la convention consiste à utiliser struct lorsque le but est de regrouper des données et d'utiliser des classes lorsque nous avons besoin d'une abstraction de données et, peut-être, d'un héritage.

    En C++, les structures et les classes sont passées par valeur, sauf explicitement déférencées. Dans d'autres langues, les classes et les structures peuvent avoir une sémantique distincte - c'est-à-dire. les objets (instances de classes) peuvent être passés par référence et les structures par valeur. Remarque: Des commentaires sont associés à cette question. Voir la page de discussion pour ajouter à la conversation.

1
yshivakathik

La différence entre class et struct est une différence entre des mots-clés et non entre des types de données. Ces deux

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

les deux définissent un type de classe. La différence des mots-clés dans ce contexte est la différence d'accès par défaut:

  • foo::x est public et foo_base est hérité publiquement
  • bar::x est privé et bar_base est hérité en privé

Bien que cela soit impliqué par d'autres réponses, il n'est pas explicitement mentionné - que les structures sont compatibles avec le langage C, en fonction de l'utilisation; les classes ne sont pas.

Cela signifie que si vous écrivez un en-tête que vous voulez être compatible avec le langage C, vous n'avez pas d'autre choix que struct (ce qui dans le monde C ne peut pas avoir de fonction, mais peut avoir un pointeur de fonction).

1
UKMonkey

Les autres réponses ont mentionné les valeurs par défaut privé/public (mais notez qu'une structure est une classe est une structure; ce ne sont pas deux éléments différents, mais deux façons de définir le même élément).

Ce qui pourrait être intéressant à noter (en particulier puisque le demandeur est susceptible d’utiliser MSVC++ puisqu'il mentionne le C++ "non géré") est que Visual C++ se plaint dans certaines circonstances si une classe est déclarée avec class puis définie avec struct (ou peut-être l'inverse), même si la norme dit que c'est parfaitement légal.

1
ymett