+ Répondre à la discussion Actualité déjà publiée
  1. #1
    Community Manager

    Avatar de Siguillaume
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    août 2007
    Messages
    4 607
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : août 2007
    Messages : 4 607
    Points : 22 726
    Points
    22 726

    Par défaut Apprendre la construction de classes en C++ avec les types et les objets de Stepanov

    Chers membres du club,

    J'ai le plaisir de vous présenter ce tutoriel de KDAB pour apprendre la construction de classes en C++ avec les types réguliers et les objets partiellement formés de Stepanov.

    Dans ce tutoriel, j'aborderai un des concepts fondamentaux introduits par Alex Stepanov et Paul McJones dans leur ouvrage de référence Elements of Programming : celui de type régulier (ou semi-régulier) (regular type) et d'état partiellement formé (partially-formed state).
    À partir de ces concepts, j'essaierai d'en déduire des règles d'implémentation en C++ de ce que l'on appelle d'habitude des « types valeur » (value types), en me concentrant sur l'essentiel, qui me semble n'avoir pas été traité suffisamment en profondeur jusqu'à présent : les fonctions membres spéciales.

    Bonne lecture et n'hésitez pas à apporter vos commentaires.


    Retrouvez les autres cours et tutoriels proposés par KDAB


    Retrouvez les meilleurs cours et tutoriels pour apprendre C++
    Vous avez envie de contribuer au sein du Club Developpez.com ? Contactez-nous maintenant !
    Vous êtes passionné, vous souhaitez partager vos connaissances en informatique, vous souhaitez faire partie de la rédaction.
    Il suffit de vous porter volontaire et de nous faire part de vos envies de contributions :
    Rédaction d'articles/cours/tutoriels, Traduction, Contribution dans la FAQ, Rédaction de news, interviews et témoignages, Organisation de défis, de débats et de sondages, Relecture technique, Modération, Correction orthographique, etc.
    Vous avez d'autres propositions de contributions à nous faire ? Vous souhaitez en savoir davantage ? N'hésitez pas à nous approcher.

  2. #2
    Membre expérimenté
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    avril 2016
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : avril 2016
    Messages : 365
    Points : 1 595
    Points
    1 595

    Par défaut

    Personnellement, je suis d'accord avec le premier commentaire de l'article original quand il dit :
    Regarding default-initialization for if/else vs ?: — I think that’s not a very strong argument. If it was the sole argument for a partially-formed state, then the safety concerns (use after lack of proper initialization) would far outweigh this minor benefit IMHO. However, it is not the sole argument. It is far easier to perform aggregation if you have a partially constructed state, since the class might not have a default value to provide to its data member.
    En particulier, quand on manipule std::array<T, N>, il est très pratique que T ait un constructeur par défaut sans le coût de l'initialisation. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include <array>
     
    class Rect {
    public:
    	Rect() noexcept = default;
    	constexpr Rect(int x1, int y1, int x2, int y2) noexcept :
    		m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2) {}
    private:
    	int m_x1, m_y1, m_x2, m_y2;
    };
     
    template<size_t N>
    std::array<Rect, N> foo()
    {
    	std::array<Rect, N> result;
    	for(size_t k = 0; k < N; ++k)
    		result[k] = Rect(k, k, k+1, k+1);
    	return result;
    }
    Mais l'absence d'initialisation est dangereuse car source de bogues non reproductibles. Pour pallier cela, on pourrait envisager que l'absence d'initialisation soit explicite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct no_init_t {} no_init;
     
    class Rect2 {
    public:
    	Rect2(no_init_t) noexcept : Rect2() {}
    	constexpr Rect2(int x1, int y1, int x2, int y2) noexcept :
    		m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2) {}
    private:
    	Rect2() noexcept = default;
    	int m_x1, m_y1, m_x2, m_y2;
    };
    Cependant, d'un autre côté, l'utilisation serait parfois plus complexe. Par exemple, réécrire la fonction foo nécessiterait du code préliminaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    namespace detail
    {
    	template<class T, size_t...iseq>
    	std::array<T, sizeof...(iseq)> make_std_array_no_init_impl(std::index_sequence<iseq...>)
    	{
    		return {{(static_cast<void>(iseq), T(no_init))...}};
    	}
    }
     
    //! Pour chaque élément, appelle le constructeur avec en argument no_init.
    template<class T, size_t N>
    std::array<T, N> make_std_array_no_init()
    {
    	return detail::make_std_array_no_init_impl<T>(std::make_index_sequence<N>());
    }
     
    template<size_t N>
    std::array<Rect2, N> foo2()
    {
    	auto result = make_std_array_no_init<Rect2, N>();
    	for(size_t k = 0; k < N; ++k)
    		result[k] = Rect2(k, k, k+1, k+1);
    	return result;
    }

  3. #3
    Expert éminent
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    août 2003
    Messages
    5 123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : août 2003
    Messages : 5 123
    Points : 9 887
    Points
    9 887

    Par défaut

    (Je reposte ici un commentaire posé dans la zone de rédaction)

    La discussion de l'auteur sur le partiellement formé n'est pas anodine. C'est un sujet qui a fortement impacté le redesign des variants, d'optional et d'autres trucs encore comparativement au design initial chez boost. Je pense que c'est un sujet sur lequel nous nous cherchons encore.

    Pour l'instant, mettre l'objet dans un état destructible (voire affectable), mais non valide (UB en cas de tentative d'exécution de certaines opérations) ne me parait absolument pas aberrant. On rejoint des problématiques de Programmation par Contrat VS programmation Défensive (quand on considère l'utilisation d'exceptions). C'est exactement la même problématique que " auto p = make_unique<T>(...); f(move(p)); p->g();". Il y a une UB sans que cela ne choque personne, non?

    Jusqu'au C++11, j'en étais arrivé à la conclusion que les constructeurs par défaut ne sont pas nos amis sur les types entités. Que sur les valeurs pourquoi pas, mais que s'il l'on peut éviter c'est aussi bien. Si maintenant on considère que l'on peut déplacer des valeurs, il y a ce problème d'état valide (qui nous offre toujours la garantie basique (de destructabilité)) mais non exploitable.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

Discussions similaires

  1. [VxiR2] "Exporter avec l'univers" dans les propriétés d'un objet
    Par Geo55 dans le forum Designer
    Réponses: 4
    Dernier message: 27/05/2011, 11h10
  2. les methodes et les associations entre les classes
    Par zin_rbt dans le forum Diagrammes de Classes
    Réponses: 1
    Dernier message: 24/05/2010, 14h41
  3. Réponses: 5
    Dernier message: 14/01/2010, 18h11
  4. Réponses: 5
    Dernier message: 08/12/2008, 12h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo