lang:cpp:classes
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| lang:cpp:classes [2020/05/17 16:44] – [Interface] : ajout de la source root | lang:cpp:classes [2025/07/28 13:38] (Version actuelle) – [Version "Rule of Zero"] : clarification du commentaire ''does not have a user-declared'' root | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| =====Sans héritage===== | =====Sans héritage===== | ||
| - | |||
| - | ====Multiples constructeurs==== | ||
| - | Il est possible d' | ||
| - | |||
| - | <code cpp> | ||
| - | class A{}; | ||
| - | class B : public A | ||
| - | { | ||
| - | | ||
| - | // Call constructor B(int) from constructor B(). | ||
| - | // Dont call the parent A() when calling another constructor of the same class. | ||
| - | B() : B(5){} | ||
| - | // Avoid default function argument | ||
| - | B(int a/* = 5*/):A(), a_(a){} | ||
| - | |||
| - | | ||
| - | int a_; | ||
| - | }; | ||
| - | </ | ||
| ====Version "Rule of Zero" | ====Version "Rule of Zero" | ||
| Ligne 24: | Ligne 5: | ||
| Cette règle s' | Cette règle s' | ||
| - | Il est aussi conseillé de réduire son utilisation aux classes n' | + | Il est aussi conseillé de réduire son utilisation aux classes n' |
| <code cpp> | <code cpp> | ||
| Ligne 32: | Ligne 13: | ||
| // Constructor. | // Constructor. | ||
| Class() = default; | Class() = default; | ||
| - | // Pas de destructeur. Pas de copy/move contructor/ | + | // Pas de définition explicite du destructeur, |
| + | // ni de copy/move contructor/ | ||
| } | } | ||
| </ | </ | ||
| Ligne 47: | Ligne 29: | ||
| < | < | ||
| - | Par '' | + | '' |
| Autre explication : [[https:// | Autre explication : [[https:// | ||
| Ligne 89: | Ligne 71: | ||
| ===Destructeur=== | ===Destructeur=== | ||
| - | Une classe doit avoir un destruteur | + | Une classe doit avoir un destructeur |
| L' | L' | ||
| Ligne 145: | Ligne 127: | ||
| < | < | ||
| const | const | ||
| + | </ | ||
| + | |||
| + | * Durée de vie d'un objet dans la pile | ||
| + | |||
| + | Si c'est un objet explicitement déclaré, le destructeur sera appelé lors du bloc fermant. | ||
| + | |||
| + | <code cpp> | ||
| + | int main() | ||
| + | { | ||
| + | A a; | ||
| + | { | ||
| + | B b; | ||
| + | // On appelle ~B() | ||
| + | } | ||
| + | // On appelle ~A() | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | La technique de mettre un bloc de crochet pour forcer un appel du destructeur à un moment précis est utilisé fréquemment par les '' | ||
| + | |||
| + | <code cpp> | ||
| + | int main() | ||
| + | { | ||
| + | std::mutex io_mutex; | ||
| + | { | ||
| + | std:: | ||
| + | std::cout << e1.id << " and " << e2.id << " are waiting for locks" << std::endl; | ||
| + | // le mutex est automatiquement libéré lors de l' | ||
| + | } | ||
| + | return 1; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Si l' | ||
| + | |||
| + | <code cpp> | ||
| + | #include < | ||
| + | |||
| + | class A | ||
| + | { | ||
| + | public: | ||
| + | A() noexcept { std::cout << " | ||
| + | ~A() noexcept { std::cout << " | ||
| + | int foo() { return 1; } | ||
| + | }; | ||
| + | |||
| + | int foo2(int a) | ||
| + | { | ||
| + | std::cout << " | ||
| + | return a; | ||
| + | } | ||
| + | |||
| + | int main() | ||
| + | { | ||
| + | std::cout << " | ||
| + | foo2(foo2(A().foo())); | ||
| + | // Le destructeur de A est appelé ici. | ||
| + | std::cout << " | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Affichage : | ||
| + | |||
| + | < | ||
| + | 0 | ||
| + | A | ||
| + | int | ||
| + | int | ||
| + | ~A | ||
| + | 1 | ||
| </ | </ | ||
| Ligne 222: | Ligne 274: | ||
| L' | L' | ||
| + | |||
| + | Mauvais : | ||
| <code cpp> | <code cpp> | ||
| Ligne 240: | Ligne 294: | ||
| D d; | D d; | ||
| f(d); | f(d); | ||
| + | </ | ||
| + | |||
| + | OK : | ||
| + | |||
| + | <code cpp> | ||
| + | #include < | ||
| + | |||
| + | class B { | ||
| + | | ||
| + | B() = default; | ||
| + | // Si on implémente ce clone, il faut mettre le constructeur par copie en public. | ||
| + | // Il est préférable de mettre ce constructeur en privée pour empêcher | ||
| + | // sa mauvaise utilisation. | ||
| + | virtual std:: | ||
| + | virtual char m() { return 1; } | ||
| + | virtual ~B() = default; | ||
| + | |||
| + | | ||
| + | // Peut être protected si clone est pure virtuelle. | ||
| + | B(const B&) = default; | ||
| + | B& operator=(const B&) = delete; | ||
| + | }; | ||
| + | |||
| + | class D : public B { | ||
| + | | ||
| + | D() = default; | ||
| + | D(const D&) = default; | ||
| + | D& operator=(const D&) = delete; | ||
| + | std:: | ||
| + | char m() override { return 10; } | ||
| + | virtual ~D() = default; | ||
| + | }; | ||
| + | |||
| + | char f(B& b) { | ||
| + | auto b2 = b.clone(); | ||
| + | return b2->m(); | ||
| + | } | ||
| + | |||
| + | int main() { | ||
| + | D d; | ||
| + | return f(d); | ||
| + | } | ||
| </ | </ | ||
| Ligne 404: | Ligne 500: | ||
| } | } | ||
| </ | </ | ||
| + | |||
| + | ====vtable==== | ||
| + | |||
| + | Il n' | ||
| + | |||
| + | <code cpp> | ||
| + | #include < | ||
| + | |||
| + | struct S { | ||
| + | int x; | ||
| + | virtual void f() {} | ||
| + | }; | ||
| + | |||
| + | int main() { | ||
| + | S s; | ||
| + | s.x = 5; | ||
| + | std::cout << "size : " << sizeof(S) << " | ||
| + | void*** ptr = (void***)& | ||
| + | std::cout << " | ||
| + | std::cout << "bytes : " << *ptr << " and " << *(ptr + 1) << " | ||
| + | std::cout << " | ||
| + | << " | ||
| + | std:: | ||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | [[http:// | ||
| + | |||
| ====override / redéfinition==== | ====override / redéfinition==== | ||
| ===Cas général=== | ===Cas général=== | ||
| Ligne 439: | Ligne 564: | ||
| Lors de l' | Lors de l' | ||
| + | |||
| + | Il est possible d' | ||
| + | |||
| + | <code cpp> | ||
| + | class A{}; | ||
| + | class B : public A | ||
| + | { | ||
| + | | ||
| + | // Call constructor B(int) from constructor B(). | ||
| + | // No need (forbidden) to call A. | ||
| + | B() : B(5){} | ||
| + | // Avoid default function argument | ||
| + | B(int a/* = 5*/):A(), a_(a){} | ||
| + | |||
| + | | ||
| + | int a_; | ||
| + | }; | ||
| + | </ | ||
| * Destructeur | * Destructeur | ||
| Ligne 446: | Ligne 589: | ||
| Pour le destructeur, | Pour le destructeur, | ||
| + | Par défaut, un destructeur est '' | ||
| ====overload / surcharge==== | ====overload / surcharge==== | ||
| * Cas général | * Cas général | ||
| Ligne 555: | Ligne 699: | ||
| std::string getName() const override | std::string getName() const override | ||
| { | { | ||
| - | return " | + | |
| } | } | ||
| }; | }; | ||
| Ligne 581: | Ligne 725: | ||
| ===Template=== | ===Template=== | ||
| - | '' | + | '' |
| + | |||
| + | <WRAP center round important 60%> | ||
| + | Ce système de masquage ne doit être appliqué que si nécessaire. | ||
| + | |||
| + | [[https:// | ||
| + | </ | ||
| Ici, '' | Ici, '' | ||
lang/cpp/classes.1589726675.txt.gz · Dernière modification : de root
