Class declaration
Les classes sont des types définis par l'utilisateur, définis par un spécificateur de classe, qui apparaît dans la decl-specifier-seq de la déclaration syntaxe.
Contenu
SyntaxeLe spécificateur de classe a la syntaxe suivante :
1) Définition de classe nommée
2) Définition de classe sans nom
Déclaration anticipéeUne déclaration de la forme suivante
Déclare un type de classe qui sera défini ultérieurement dans cette portée. Jusqu'à ce que la définition apparaisse, ce nom de classe a un type incomplet . Cela permet à des classes qui se référencent mutuellement : class Vector; // déclaration anticipée class Matrix { // ... friend Vector operator*(const Matrix&, const Vector&); }; class Vector { // ... friend Vector operator*(const Matrix&, const Vector&); }; et si un fichier source particulier n'utilise que des pointeurs et des références vers la classe, cela permet de réduire #include les dépendances : // Dans MyStruct.h #include <iosfwd> // contient la déclaration anticipée de std::ostream struct MyStruct { int value; friend std::ostream& operator<<(std::ostream& os, const S& s); // définition fournie dans le fichier MyStruct.cpp qui utilise #include <ostream> }; Si une déclaration anticipée apparaît dans une portée locale, elle masque la classe, variable, fonction précédemment déclarée, et toutes les autres déclarations du même nom pouvant apparaître dans les portées englobantes : struct s { int a; }; struct s; // ne fait rien (s est déjà défini dans cette portée) void g() { struct s; // déclaration anticipée d'une nouvelle structure locale "s" // cela masque la structure globale s jusqu'à la fin de ce bloc s* p; // pointeur vers la structure locale s struct s { char* p; }; // définition de la structure locale s } Notez qu'un nouveau nom de classe peut également être introduit par un elaborated type specifier qui apparaît comme partie d'une autre déclaration, mais seulement si name lookup ne peut pas trouver une classe précédemment déclarée avec le même nom. class U; namespace ns { class Y f(class T p); // déclare la fonction ns::f et déclare ns::T et ns::Y class U f(); // U fait référence à ::U // peut utiliser des pointeurs et références vers T et Y Y* p; T* q; } Spécification des membresLa spécification des membres, ou le corps d'une définition de classe, est une séquence entre accolades d'un nombre quelconque des éléments suivants :
1)
Les déclarations de membres de la forme
Cette déclaration peut déclarer des données membres statiques et non statiques, des fonctions membres , des typedefs membres , des énumérations membres et des classes imbriquées . Elle peut également être une déclaration friend . class S { int d1; // non-static data member int a[10] = {1, 2}; // non-static data member with initializer (C++11) static const int d2 = 1; // static data member with initializer virtual void f1(int) = 0; // pure virtual member function std::string d3, *d4, f2(int); // two data members and a member function enum { NORTH, SOUTH, EAST, WEST }; struct NestedS { std::string s; } d5, *d6; typedef NestedS value_type, *pointer_type; };
2)
Définitions de fonctions, qui déclarent et définissent à la fois
les fonctions membres
ou
les fonctions amies
. Un point-virgule après une définition de fonction membre est optionnel. Toutes les fonctions définies dans le corps d'une classe sont automatiquement
inline
, sauf si elles sont attachées à un
module nommé
(depuis C++20)
.
class M { std::size_t C; std::vector<int> data; public: M(std::size_t R, std::size_t C) : C(C), data(R*C) {} // constructor definition int operator()(std::size_t r, std::size_t c) const // member function definition { return data[r * C + c]; } int& operator()(std::size_t r, std::size_t c) // another member function definition { return data[r * C + c]; } };
3)
Spécificateurs d'accès
public:
,
protected:
, et
private:
class S { public: S(); // constructeur public S(const S&); // constructeur de copie public virtual ~S(); // destructeur virtuel public private: int* ptr; // membre de données privé };
4)
Déclarations using
:
class Base { protected: int d; }; class Derived : public Base { public: using Base::d; // rendre le membre protégé d de Base un membre public de Derived using Base::Base; // hériter de tous les constructeurs des classes de base (C++11) };
5)
static_assert
déclarations :
template<typename T> struct Foo { static_assert(std::is_floating_point<T>::value, "Foo<T>: T must be floating point"); };
6)
déclarations de modèles membres
:
struct S { template<typename T> void f(T&& n); template<class CharT> struct NestedS { std::basic_string<CharT> s; }; };
Classes localesUne déclaration de classe peut apparaître dans le corps d'une fonction, auquel cas elle définit une classe locale . Le nom d'une telle classe n'existe que dans la portée de la fonction, et n'est pas accessible à l'extérieur.
Exécuter ce code
#include <algorithm> #include <iostream> #include <vector> int main() { std::vector<int> v{1, 2, 3}; struct Local { bool operator()(int n, int m) { return n > m; } }; std::sort(v.begin(), v.end(), Local()); // since C++11 for (int n : v) std::cout << n << ' '; std::cout << '\n'; } Sortie : 3 2 1 Mots-clésRapports de défautsLes rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
Voir aussi
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||