Share via


Système de type C++ (C++ moderne)

Le concept de type est très important en C++.Chaque variable, argument de fonction, et la valeur de retour de fonction doivent avoir un type pour être compilés.De plus, chaque expression (valeurs littérales) est implicitement donnée un type par le compilateur avant d'être évaluée.Quelques exemples des types incluent int pour stocker des valeurs intégrales, double stocker des valeurs à virgule flottante (également appelés types de données scalaires ), ou la classe standard std::basic_string de bibliothèque pour stocker le texte.Vous pouvez créer votre propre type en définissant class ou struct.Le type spécifie la quantité de mémoire qui est allouée pour la variable (ou le résultat de l'expression), les types de valeurs qui peuvent être stockées dans cette variable, comment ces valeurs (comme modèles binaires) sont interprétées, et les opérations qui peuvent être exécutés dessus.Cet article contient une vue d'ensemble informelle des principales fonctionnalités du système de type C++.

Terminologie

Variable: Le nom symbolique d'une quantité de données afin que le nom peut être utilisé pour accéder aux données il fait référence dans toute la portée du code où il est défini.En C++, « variable » est généralement utilisé pour faire référence à des instances des types de données scalaires, alors que les instances d'autres types sont généralement appelées « objet ».

Objet: Pour plus de simplicité et la sécurité, cet article utilise le terme « objet » pour faire référence à une instance d'une classe ou d'une structure, et lorsqu'il est utilisé en général inclut tous les types, même variables scalaires.

Type POD (plain old data) : Cette catégorie informelle des types de données C++ fait référence aux types qui sont scalaires (consultez les types fondamentaux section) ou sont des classes POD.Une classe POD n'a aucune donnée membre statique qui ne sont pas des cosses, et n'a aucun constructeur défini par l'utilisateur, destructeur défini par l'utilisateur, ou opérateur d'assignation défini par l'utilisateur.En outre, une classe POD n'a aucune fonction virtuelle, aucune classe de base, et données membre non static pas privées et protégées.Les types POD sont souvent utilisés pour l'échange de données externes, par exemple à un module écrit en langage C (qui est de type POD uniquement).

Spécifier les types de variable et de fonction

C++ est un langage fortement typé et il statique- est également tapé; chaque objet a un type et ce type ne change jamais (à ne pas confondre avec les objets de données statiques).
Lorsque vous déclarez une variable dans votre code, vous devez spécifier ou son type explicitement, ou utilisez le mot clé d' auto pour indiquer au compilateur de déduire le type de l'initialiseur.
Lorsque vous déclarez une fonction dans votre code, vous devez spécifier le type de chaque argument et sa valeur de retour, ou void si aucune valeur n'est retournée par la fonction.L'exception est lorsque vous utilisez des modèles de fonctions, qui permettent des arguments des types arbitraires.

Une fois que vous déclariez d'abord une variable, vous ne pouvez pas modifier son type à certains débogage ultérieur.Toutefois, vous pouvez copier la valeur de retour de la valeur de variable ou d'une fonction dans une autre variable d'un type différent.De telles opérations sont appelées des conversions de type, qui sont parfois requises mais sont également des sources possibles de perte ou d'inexactitude de données.

Lorsque vous déclarez une variable de type POD, nous vous recommandons fortement l'initialisons, c'est-à-dire pour lui donner une valeur initiale.Jusqu'à ce que vous initialisé une variable, elle a la valeur « garbage collector » constitué que est ce que bits se sont avérés justement être dans cet emplacement de mémoire précédemment.C'est un aspect important du C++ à mémoriser, surtout si vous accédez à partir d'un autre langage qui traite l'initialisation pour vous.Lorsque vous déclarez une variable de type classe non POD, le constructeur traite l'initialisation.

L'exemple suivant montre des déclarations de variable simple avec des descriptions pour chacun.L'exemple montre également comment le compilateur utilise les informations de type pour autoriser ou interdire certaines opérations suivantes dans la variable.

    int result = 0;              // Declare and initialize an integer.
    double coefficient = 10.8;   // Declare and initialize a floating 
                                 // point value.
    auto name = "Lady G.";       // Declare a variable and let compiler 
                                 // deduce the type.
    auto address;                // error. Compiler cannot deduce a type 
                                 // without an intializing value.
    age = 12;                    // error. Variable declaration must
                                 // specify a type or use auto!
    result = "Kenny G.";         // error. Can’t assign text to an int.
    string result = "zero";      // error. Can’t redefine a variable with
                                 // new type.
    int maxValue;                // Not recommended! maxValue contains 
                                 // garbage bits until it is initialized.

Types (intégrés) fondamentaux

Contrairement à certains langages, C++ n'a aucun type de base universel dont tous les autres types dérivés de.L'implémentation d' Visual C++ du langage inclut de nombreux types fondamentaux, également appelés types intégrés.Cela inclut les types numériques comme int, double, long, bool, plus les types d' char et d' wchar_t pour ASCII et des caractères Unicode, respectivement.La plupart de concept fondamental types (sauf bool, double, wchar_t et les types connexes) tout ont des versions non signés, qui modifient la plage de valeurs que la variable peut stocker.Par exemple, int, qui stocke un entier 32 bits signé, peut représenter une valeur de -2.147.483.648 à 2.147.483.647.unsigned int, qui est également stocké comme 32 bits, peut stocker une valeur de 0 à 4.294.967.295.Tout le nombre de valeurs possibles dans chaque cas sont identiques ; uniquement la plage est différent.

Les types fondamentaux sont identifiés par le compilateur, qui a des règles intégrées qui régissent les opérations vous pouvez effectuer sur elles, et comment elles peuvent être converties en d'autres types fondamentaux.Pour une liste complète des types intégrés et leurs limites de taille et numériques, consultez Types fondamentaux (C++).

L'illustration suivante montre les tailles relatives des types intégrés :

Taille en octets des types intégrés

Le tableau suivant répertorie le plus souvent les types fondamentaux utilisés :

Type

Taille

Commentaire

int

4 octets

L'option par défaut pour les valeurs intégrales.

double

8 octets

L'option par défaut des valeurs à virgule flottante.

bool

1 octet

Représente des valeurs qui peuvent être true ou false.

char

1 octet

Utilisation des caractères ASCII dans les chaînes de style C plus anciennes ou des objets std::string qui ne doivent jamais être convertis en UNICODE.

wchar_t

2 octets

Représente les valeurs de caractère « larges » qui peuvent être au format Unicode format encodé (UTF-16 sur windows, d'autres systèmes d'exploitation peut différer).C'est le type de caractère utilisé dans les chaînes de type std::wstring.

unsigned char

1 octet

C++ n'a aucun type prédéfini d' byte .Utilisez le caractère non signé pour représenter une valeur d'octet.

unsigned int

4 octets

Option par défaut des bits indicateurs.

pendant longtemps

8 octets

Représente des valeurs entières très grandes.

Le type void

Le type d' void est un type particulier ; vous ne pouvez pas déclarer une variable de type void, mais vous pouvez déclarer une variable du type void * (pointeur vers void), qui est parfois nécessaire en allouant la mémoire (non ordonnée) brut.Toutefois, les pointeurs vers void ne sont pas de type sécurisé et généralement leur utilisation est fortement découragée en C++ récent.Dans une déclaration de fonction, une valeur de retour d' void signifie que la fonction ne retourne pas de valeur ; il s'agit d'une utilisation courante et acceptable d' void.Lorsque le langage C exigeait les fonctions qui ont des paramètres zéro pour déclarer void dans la liste de paramètres, par exemple, fou(void), cette pratique est découragée en C++ récent et doit être déclarée fou().Pour plus d'informations, consultez Conversions de type et sécurité de type (C++ moderne).

const qualificateur de type

Tout élément ou type défini par l'utilisateur peut être qualifié par le mot clé const.En outre, les fonctions membres peuvent être const- qualifié et même const- surchargé.La valeur d'un type d' const ne peut pas être modifiée après son initialisation.

    const double PI = 3.1415;
    PI = .75 //Error. Cannot modify const variable.

Le qualificateur d' const est largement utilisé dans la fonction et les déclarations de variable et l'exactitude « const » est un concept important en C++ ; essentiellement qui signifie pour utiliser const pour garantir, au moment de la compilation, les valeurs ne sont pas modifiées involontairement.Pour plus d'informations, consultez const (C++).

Un type d' const est distinct de sa version non-const ; par exemple, const int est un type distinct d' int.Vous pouvez utiliser l'opérateur C++ const_cast à ces occasions rares où vous devez supprimer le const- ness d'une variable.Pour plus d'informations, consultez Conversions de type et sécurité de type (C++ moderne).

Types de chaînes

À proprement parler, le langage C++ n'a aucun type prédéfini « chaîne » ; char et caractères uniques de mémoire d' wchar_t – vous devez déclarer un tableau de ces types pour rapprocher une chaîne, en ajoutant une valeur NULL se terminante (par exemple, ‘\0’ASCII) à l'élément de tableau un au delà de le dernier caractère valide (également appelé « chaîne de style C ").Les chaînes de style C requises de beaucoup plus de code d'être écrit ou l'utilisation des fonctions de bibliothèque de services externes de chaîne.Mais en C++ récent, nous avons les types de bibliothèque de std::string standard (pour les chaînes de caractères de type de 8 bits de char) ou std::wstring (pour les chaînes de caractères de type 16 bits de wchar_t).Ces conteneurs STL peuvent être considérés comme des types natifs chaîne car ils font partie des bibliothèques standard qui sont incluses dans tout environnement conforme de génération C++.Utilisez simplement la directive d' #include <string> pour rendre ces types disponibles dans votre programme.(Si vous utilisez MFC ou ATL, la classe de CString est également disponible, mais ne fait pas partie de la norme C++.) L'utilisation des tableaux de caractères se terminant par null (les chaînes de style C mentionnées précédemment) est fortement découragée en C++ récent.Pour plus d'informations sur la façon de déterminer le type chaîne à utiliser dans un programme moderne C++, et comment convertir entre les différents types, consultez à Chaînes et texte (C++ moderne).

Types définis par l'utilisateur

Lorsque vous définissez class, struct, union, ou enum, que l'élément est utilisé dans le reste du code comme s'il s'agissait d'un type fondamental.Il a une taille de la mémoire, et certaines règles sur la façon dont elle peut être utilisée s'appliquent à celui-ci pour le contrôle de compilation et, au moment de l'exécution, pour la durée de vie de votre programme.Les principales différences entre les types intégrés fondamentaux et des types définis par l'utilisateur sont les suivantes :

  • Le compilateur n'a aucune connaissance intégrée d'un type défini par l'utilisateur.Il « apprend » du type lorsqu'il rencontre d'abord la définition pendant le processus de compilation.

  • Vous spécifiez les opérations peuvent être exécutées sur votre type, et comment il peut être converti en d'autres types, en définissant (via la surcharge) les opérateurs appropriés, en tant que membres de classe ou fonctions non - membres.Pour plus d'informations, consultez Surcharge.

  • Ils ne doivent pas être typés statiquement (la règle d'un type d'objet ne change jamais).Dans les mécanismes de l'héritage et le polymorphisme, une variable déclarée comme type défini par l'utilisateur de classe (référencée comme une instance de l'objet d'une classe) peut avoir un autre type au moment de l'exécution qu'au moment de la compilation.Pour plus d'informations, consultez Classes dérivées.

Types de pointeur

Remontant vers les versions antérieures du langage C, C++ continue à vous permettre de déclarer une variable d'un type pointeur à l'aide de le déclarateur spécial * (astérisque).Un type pointeur stocke l'adresse de l'emplacement en mémoire où la valeur de données réelle est signalée.En C++ récent, ils sont appelés bruts pointeurs, et sont accessibles dans votre code via les opérateurs spéciaux * (astérisque) ou -> (tiret avec supérieur à).Cela est appelé déréférencement, et celles que vous utilisez dépend de si vous déréférencez un pointeur vers une variable scalaire ou un pointeur vers un membre d'un objet.Utilisation des types pointeur long a été l'un des aspects les plus provocants et les plus embrouillants du développement de programmes C et C++.Cette section décrit les grandes lignes de faits et des pratiques d'aider à utiliser les pointeurs bruts si vous le souhaitez, mais en C++ moderne nécessaire (ou n'est recommandé) plus pour utiliser les pointeurs bruts pour la propriété d'objet du tout, en raison de l'évolution d' pointeur intelligent (expliqué à la fin de cette section).Il est toujours utile et possible d'utiliser des pointeurs bruts pour observer des objets, mais si vous devez les utiliser pour la propriété d'objet, vous devez le faire avec précaution et très révision consciencieux de la façon dont les objets appartenant à eux sont créés et détruits.

La première chose que vous devez connaître déclare une variable pointeur brut allouera uniquement la mémoire requise pour stocker une adresse de l'emplacement de mémoire que le pointeur se rapportera lorsqu'il est déréférencé.L'allocation de la mémoire pour la valeur de données elle-même (également appelée magasin de stockage) n'est pas toujours allouée.En d'autres termes, lorsque vous déclarez une variable pointeur brut, vous créez une variable d'adresse mémoire, et non une variable réelle de données.Déréférence une variable pointeur avant de vous assurer qu'il contient une adresse valide à un magasin de stockage provoque un comportement non défini (généralement une erreur irrécupérable) dans votre programme.L'exemple suivant illustre ce type d'erreur :

    int* pNumber;       // Declare a pointer-to-int variable.
    *pNumber = 10;      // error. Although this may compile, it is
                        // a serious error. We are dereferencing an
                        // uninitialized pointer variable with no
                        // allocated memory to point to.

L'exemple déréférence un type pointeur sans effectuer de toute mémoire pour stocker des données entières réelles ou une adresse mémoire valide assignée à celui-ci.Le code suivant corrige ces erreurs :

    int number = 10;          // Declare and initialize a local integer
                              // variable for data backing store.
    int* pNumber = &number;   // Declare and initialize a local integer
                              // pointer variable to a valid memory
                              // address to that backing store.
...
    *pNumber = 41;            // Dereference and store a new value in 
                              // the memory pointed to by
                              // pNumber, the integer variable called
                              // “number”. Note “number” was changed, not
                              // “pNumber”.

La mémoire locale corrigé de pile d'exemple utilise du code pour créer le magasin de stockage lequel pNumber indique.Nous utilisons un type fondamental pour plus de simplicité.En pratique, le magasin de stockage pour les pointeurs sont des types le plus souvent définis par l'utilisateur qui dynamique- sont alloués dans une zone de mémoire appelle le tas (ou « mémoire libre ") à l'aide d'une expression de mot clé d' new (dans la programmation de style C, la fonction de la bibliothèque Runtime antérieure d' malloc() c.a été utilisé).Une fois allouées, ces « variable » est généralement sous le nom de « objet », surtout si elles sont basées sur une définition de classe.La mémoire qui est allouée avec new doit être supprimée par une instruction correspondante d' delete (ou, si vous avez utilisé la fonction d' malloc() pour l'allocation, la fonction d'exécution free()C).

Toutefois, il est facile d'oublier de supprimer un objet dynamique- alloué particulièrement complexe, dans le code qui provoque un bogue de ressource appelé une fuite de mémoire.Pour cette raison, l'utilisation des pointeurs bruts est fortement découragée en C++ récent.Il est presque toujours préférable d'encapsuler un pointeur brut dans pointeur intelligent, qui publiera automatiquement la mémoire lorsque son destructeur est appelé lorsque le code est hors de la portée du pointeur intelligent) ; en utilisant des pointeurs intelligents vous éliminez presque complètement une classe entière des bogues dans vos programmes C++.Dans l'exemple suivant, supposez qu' MyClass est un type défini par l'utilisateur qui a une méthode DoSomeWork();publiques

void someFunction() {
    unique_ptr<MyClass> pMc(new MyClass);
    pMc->DoSomeWork();
}
  // No memory leak. Out-of-scope automatically calls the destructor
  // for the unique_ptr, freeing the resource.

Pour plus d'informations sur les pointeurs intelligents, consultez Pointeurs intelligents (C++ moderne).

Pour plus d'informations sur les conversions de pointeur, consultez Conversions de type et sécurité de type (C++ moderne).

Pour plus d'informations sur les pointeurs afficher en général le Pointeurs.

Types de données windows

Dans Win32 classique pour la programmation C et C++, la plupart des fonctions utilisent des typedefs de détail des fenêtres et des macros #define (définis dans windef.h) pour spécifier les types des paramètres et valeurs de retour.Ces types de données « windows » sont principalement uniquement des noms spéciaux (alias) fournis aux types intégrés C/C++.Pour une liste complète de ces définitions de types et définitions de préprocesseur, consultez Windows Data Types.Certains de ces définitions de types, tels que le HRESULT et le LCID, sont utiles et descriptifs.D'autres, tel que int, n'ont aucune signification particulière et sont simplement des alias pour les types fondamentaux C++.D'autres types de données windows ont des noms qui sont conservés des jours de programmation C et les processeurs 16 bits, et n'ont aucun objectif ou signifier sur le matériel ou les systèmes d'exploitation actuels.Il existe également des types de données spéciaux associés à la bibliothèque Runtime windows, comme indiqué Windows Runtime base data types.En C++ récent, la règle générale consiste à préférer les types fondamentaux C++ à moins que le type de fenêtres communique une signification supplémentaire sur la manière dont la valeur doit être interprétée.

Informations supplémentaires

Pour plus d'informations sur le système de type C++, consultez les rubriques suivantes.

Types valeur (C++ moderne)

Décrit les types valeur avec des problèmes concernant leur utilisation.

Conversions de type et sécurité de type (C++ moderne)

Décrit les problèmes de conversion de type courantes et indique comment les éviter.

Voir aussi

Autres ressources

Accueil vers C++ (C++ moderne)

Guide de référence du langage C++

Référence de la bibliothèque C++ standard