Outils pour utilisateurs

Outils du site


lang:cpp:classes

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
lang:cpp:classes [2021/03/28 17:08] – Ajout d'une implémentation de "clone" rootlang: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'appeler un constructeur depuis un autre constructeur. C'est pratique si on souhaite avoir deux constructeurs très proche. 
- 
-Bien qu'on soit dans le paragraphe sans héritage, j'ai mis un cas avec héritage pour montrer qu'on a pas besoin d'appeler le constructeur du parent si on appelle un autre constructeur. 
- 
-<code cpp> 
-class A{}; 
-class B : public A 
-{ 
- public: 
-  // 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){} 
- 
- private: 
-  int a_; 
-}; 
-</code> 
  
 ====Version "Rule of Zero"==== ====Version "Rule of Zero"====
Ligne 26: Ligne 5:
 Cette règle s'applique lorsque la classe ne gère pas de ressources. Cette règle s'applique lorsque la classe ne gère pas de ressources.
  
-Il est aussi conseillé de réduire son utilisation aux classes n'étant pas polymorphique pour éviter les problèmes de slicing.+Il est aussi conseillé de réduire son utilisation aux classes n'étant pas polymorphiques (avec une méthode virtuelle) pour éviter les problèmes de slicing.
  
 <code cpp> <code cpp>
Ligne 34: Ligne 13:
   // Constructor.   // Constructor.
   Class() = default;   Class() = default;
-  // Pas de destructeur. Pas de copy/move contructor/assignment operator+  // Pas de définition explicite du destructeur
 +  // ni de copy/move contructor/assignment operator
 } }
 </code> </code>
Ligne 49: Ligne 29:
 <cite>[[https://stackoverflow.com/questions/40959659/c-rule-of-zero-what-is-user-declared-constructor|C++ Rule of Zero & what is "user-declared" constructor?]] {{ :lang:cpp:class:c_rule_of_zero_what_is_user-declared_constructor_-_stack_overflow_2020-03-09_23_01_28_.html |Archive du 04/12/2016 le 09/03/2020}}</cite></blockquote> <cite>[[https://stackoverflow.com/questions/40959659/c-rule-of-zero-what-is-user-declared-constructor|C++ Rule of Zero & what is "user-declared" constructor?]] {{ :lang:cpp:class:c_rule_of_zero_what_is_user-declared_constructor_-_stack_overflow_2020-03-09_23_01_28_.html |Archive du 04/12/2016 le 09/03/2020}}</cite></blockquote>
  
-Par ''does not have a user-declared'', cela signifie aussi ne pas utiliser ''= default;''.+''does not have a user-declared'' signifie également ne pas utiliser ''= default;''.
  
 Autre explication : [[https://www.fluentcpp.com/2019/04/23/the-rule-of-zero-zero-constructor-zero-calorie/|The Rule of Zero in C++]] {{ :lang:cpp:class:the_rule_of_zero_in_c_-_fluent_c_2019-12-18_23_16_30_.html |Archive du 23/04/2019 le 18/12/2019}} Autre explication : [[https://www.fluentcpp.com/2019/04/23/the-rule-of-zero-zero-constructor-zero-calorie/|The Rule of Zero in C++]] {{ :lang:cpp:class:the_rule_of_zero_in_c_-_fluent_c_2019-12-18_23_16_30_.html |Archive du 23/04/2019 le 18/12/2019}}
Ligne 91: Ligne 71:
 ===Destructeur=== ===Destructeur===
  
-Une classe doit avoir un destruteur virtuel si l'héritage est utilisée et que l'une des classes (elle, enfant ou parent) gère des ressources.+Une classe doit avoir un destructeur virtuel si l'héritage est utilisé et que l'une des classes (elle, enfant ou parent) gère des ressources. Cela inclut aussi des membres de type classe qui gère des ressources (par exemple ''std::string''), soit presque toutes les classes.
  
 L'attribut ''virtual'' doit être placé dans la classe la plus parent. L'attribut ''virtual'' doit être placé dans la classe la plus parent.
Ligne 172: Ligne 152:
   std::mutex io_mutex;   std::mutex io_mutex;
   {   {
-    std::lock_guard<std::mutex> lk(io_mutex);+    std::scoped_lock<std::mutex> lk(io_mutex);
     std::cout << e1.id << " and " << e2.id << " are waiting for locks" << std::endl;     std::cout << e1.id << " and " << e2.id << " are waiting for locks" << std::endl;
     // le mutex est automatiquement libéré lors de l'appel du destructeur de lk.     // le mutex est automatiquement libéré lors de l'appel du destructeur de lk.
Ligne 520: Ligne 500:
 } }
 </code> </code>
 +
 +====vtable====
 +
 +Il n'existe pas de norme pour savoir où est l'adresse du pointeur de la table virtuelle. Cependant, en tout logique, c'est la première donnée de la classe.
 +
 +<code cpp>
 +#include <iostream>
 +
 +struct S {
 +  int x;
 +  virtual void f() {}
 +};
 +
 +int main() {
 +  S s;
 +  s.x = 5;
 +  std::cout << "size : " << sizeof(S) << "\n";
 +  void*** ptr = (void***)&s;
 +  std::cout << "address : " << ptr << "\n";
 +  std::cout << "bytes : " << *ptr << " and " << *(ptr + 1) << "\n";
 +  std::cout << "address if vftable : " << *ptr << "\naddress of f : " << **ptr
 +            << "\n";
 +  std::cin.get();
 +  return 0;
 +}
 +</code>
 +
 +[[http://www.cplusplus.com/forum/general/33019/|detemine vtable address]] {{ :lang:cpp:class:detemine_vtable_address_-_c_forum_2021-06-21_00_03_46_.html |Archive du 13/12/2010 le 22/06/2021}}
 +
 ====override / redéfinition==== ====override / redéfinition====
 ===Cas général=== ===Cas général===
Ligne 555: Ligne 564:
  
 Lors de l'instantiation d'une classe, un constructeur sera systématiquement appelé à chaque niveau d'héritage, en commençant par celui en bas de la hiérarchie. Lors de l'instantiation d'une classe, un constructeur sera systématiquement appelé à chaque niveau d'héritage, en commençant par celui en bas de la hiérarchie.
 +
 +Il est possible d'appeler un constructeur depuis un autre constructeur. C'est pratique si on souhaite avoir deux constructeurs très proche.
 +
 +<code cpp>
 +class A{};
 +class B : public A
 +{
 + public:
 +  // 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){}
 +
 + private:
 +  int a_;
 +};
 +</code>
  
   * Destructeur   * Destructeur
lang/cpp/classes.1616944110.txt.gz · Dernière modification : de root