IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Init() vs Constructeur


Sujet :

C++

  1. #1
    r0d
    r0d est d�connect�
    Membre exp�riment�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 297
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 4 297
    Billets dans le blog
    2
    Par d�faut Init() vs Constructeur
    Bonjour � tous,

    un petit probl�me de conception m'a amen� � me poser la question suivante: Quelle sont les diff�rences fondamentales entre le constructeur d'une classe et sa m�thode Init()?

    Ce qui engendre tout un tas de questions:
    - O� doit-on faire l'allocation de m�moire pour les membres (tableaux, etc.)?
    - Si l'on a des param�tres � passer pour construire et/ou initialiser sa classe, doit-on plut�t les passer au constructeur ou la la m�thode Init()?
    - Que doit-on mettre dans l'un et pas dans l'autre?

    Merci.

  2. #2
    Membre chevronn� Avatar de xxiemeciel
    Inscrit en
    Juin 2005
    Messages
    371
    D�tails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 371
    Par d�faut
    Salut,

    Personnellement je dirais que ca depend pas mal de ce que tu veux faire. Certaines classe peuvent avoir des membres dont elles n'ont pas la memoire a gerer, dans ce cas la destruction est laisser a celui qui l'a allou�.

    Sinon la plupart du temps tu alloues ta memoire dans le constructeur et tu laliberes dans le destructeur.

    Pour la methode init, elle est surtout utile lorsque le meme objet a besoin d'etre reutiliser plusieurs fois et que tu veux reinitialiser ton objet sans pour autant reallouer toute ta memoire. Ou tout simplement reinitialiser ton objet sans avoir a en instancier un nouveau.

    XXiemeciel

  3. #3
    Inactif  

    Homme Profil pro
    Ing�nieur test de performance
    Inscrit en
    D�cembre 2003
    Messages
    1 986
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 51
    Localisation : France, Bouches du Rh�ne (Provence Alpes C�te d'Azur)

    Informations professionnelles :
    Activit� : Ing�nieur test de performance
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : D�cembre 2003
    Messages : 1 986
    Par d�faut
    Salut.

    J'ai toujours des difficult�s de choix entre initialiser dans le constructeur ou avoit une m�thode d'initialisation.

    Lorsque tu utilises une m�thode, tu as une valeur de retour que tu peux tester.
    Pour le constructeur, tu peux passer en param�tre une r�f�rence qui pourra faire office de valeur de retour et qui te permettra de savoir si ton objet est bien construit.

    Le probl�me est l�, un objet peut ne pas �tre enti�rement construit si une exception se produit. Tu peux alors te retrouver avec des fuites de m�moire, voir m�me un plantage, selon ta gestion d'erreurs.

    Personnellement, je choisi la s�curit� et dans le constructeur, je fais des initialisations simples et sans risques (pointeur � NULL, assignation de valeur pour les types courants, etc...).

    Dans le livre "le langage C++", on te parle de ce probl�me, mais on ne te donne pas vraiment de solution. Tu as le choix, mais tu es pr�venu.

  4. #4
    R�dacteur/Mod�rateur
    Avatar de JolyLoic
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    5 463
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 51
    Localisation : France, Yvelines (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 5 463
    Par d�faut
    Le constructeur est une fonction sp�ciale appel�e automatiquement � certains endroits, une fonction init n'est aucune s�mantique sp�ciale, l'utilisateur doit l'appeler manuellement (risque d'oubli).

    En r�gle g�n�rale, je dirais qu'il faut utiliser uniquement un constructeur. Dans certains cas, on n'a pas assez d'infos � la construction de l'objet pour tout initialiser, d'o� une fonction init, mais c'est assez rare.

    Pour signaler une erreur dans le constructeur, il peut lancer une exception, et dans ce cas, l'objet n'est pas construit du tout.

    S'il est bien programm�, cette tentative de construction n'aura pas allou� de resosurces sans les lib�rer. Sinon, �a peut poser des probl�mes. Mais �crire un constructeur correctement vis � vis des exceptions est du m�me niveau de difficult� que d'�crire une fonction init correctement vis � vis des exceptions.
    Ma session aux Microsoft TechDays 2013 : D�velopper en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage � la d�couverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'h�sitez pas � me contacter.

  5. #5
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    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 296
    Par d�faut
    +1 � la r�ponse de Lo�c.
    Je vois les fonctions init() comme un archaisme utilis� par certains qui tiennent � les pr�senter avant les constructeurs, et une n�cessit� dans les extr�mes rares cas o� l'on a besoin de post-construction polymorphique -- si je puis dire.
    Mais l�, mieux vaut, AMA, les encapsuler dans une fonction type factory qui se charge de la construction et de la post-construction.

    Dans 99% des cas je fais tout dans le constructeur, voire je fusionne le r�sidu init() dans le constructeur principal des classes qu'il m'arrive de refactorer. C'est idiot, mais cela �vite les fuites propres �
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    T * t = new T();
    t->init(); // peut lever une exception, parce que la clé de connection n'est pas valide...
    return t;
    (oui, les auto_ptr<> sont parfaitement adapt�s ici, et correspondent au second patch que j'applique � ce genre de code)
    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...

  6. #6
    r0d
    r0d est d�connect�
    Membre exp�riment�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 297
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 4 297
    Billets dans le blog
    2
    Par d�faut
    Merci pour vos r�ponses,

    il semblerait donc que ma fonction Init() soit superflue. Il se trouve cependant que je n'ai pas le choix, elle fait partie du cahier des charges, et du coup, je suis bien oblig� de mettre quelque chose dedans...

    Citation Envoy� par Luc Hermitte
    [...] et une n�cessit� dans les extr�mes rares cas o� l'on a besoin de post-construction polymorphique -- si je puis dire.
    je ne comprends pas, pourrais-tu m'expliquer un peu ce que tu veux dire s'il te plait? Qu'est-ce qu'une post-construction polymorphique?

    Citation Envoy� par Luc Hermitte
    Mais l�, mieux vaut, AMA, les encapsuler dans une fonction type factory qui se charge de la construction et de la post-construction.
    Ok pour l'encapsulation dans une fonction de type factory. Mais qu'est-ce que AMA?

    Citation Envoy� par Luc Hermitte
    [...] cela �vite les fuites propres �
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    T * t = new T();
    t->init(); // peut lever une exception, parce que la clé de connection n'est pas valide...
    return t;
    (oui, les auto_ptr<> sont parfaitement adapt�s ici, et correspondent au second patch que j'applique � ce genre de code)
    Je ne comprends pas ce que tu veux montrer ici Pourrais-tu me donner quelques explications s'il te plait?

    Citation Envoy� par JolyLoic
    S'il est bien programm�, cette tentative de construction n'aura pas allou� de resosurces sans les lib�rer.
    Si j'ai bien compris, si on a une construction du type:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    MaClasse::MaClasse(int iValue)
    {
       m_aiMonTableau = new int(iValue);
       try
       {
          m_pMonObjet->Connect(); // connection à une bdd par exemple
       }
     
       catch (CMyConnectionException* pEx)
       {
          pEx->ReportError();
       }
    }
    On risque d'allouer le tableau m_aiMonTableau alors que la classe n'est pas construite? (dans le cas o� le connect() renvoie une exception)
    Il faudrait alors rajouter un delete[] m_aiMonTableau; dans le catch. C'est �a?


    Encore merci

  7. #7
    R�dacteur/Mod�rateur
    Avatar de JolyLoic
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    5 463
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 51
    Localisation : France, Yvelines (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 5 463
    Par d�faut
    Citation Envoy� par r0d
    Citation Envoy� par Luc Hermitte
    [...] et une n�cessit� dans les extr�mes rares cas o� l'on a besoin de post-construction polymorphique -- si je puis dire.
    je ne comprends pas, pourrais-tu m'expliquer un peu ce que tu veux dire s'il te plait? Qu'est-ce qu'une post-construction polymorphique?
    Un constructeur ne peut pas �tre polymorphe, ni appeler une fonction de sa classe de mani�re polymorphe. Exemple : La classe de base Figue a une fonction draw virtuelle pure. On veut dans le constructeur de chaque figure l'afficher. On ne peut pas directement. On doit alors demander � l'utilisateur d'appeler lui m�me la fonction draw apr�s la cration. Il s'agit d'une �tape post construction, qui est polymorphique.

    Citation Envoy� par r0d
    Citation Envoy� par Luc Hermitte
    Mais l�, mieux vaut, AMA, les encapsuler dans une fonction type factory qui se charge de la construction et de la post-construction.
    Ok pour l'encapsulation dans une fonction de type factory. Mais qu'est-ce que AMA?
    AMA = A mon avis.
    Citation Envoy� par r0d
    Citation Envoy� par Luc Hermitte
    [...] cela �vite les fuites propres �
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    T * t = new T();
    t->init(); // peut lever une exception, parce que la clé de connection n'est pas valide...
    return t;
    (oui, les auto_ptr<> sont parfaitement adapt�s ici, et correspondent au second patch que j'applique � ce genre de code)
    Je ne comprends pas ce que tu veux montrer ici Pourrais-tu me donner quelques explications s'il te plait?
    Si init l�ve une exception, la m�moire (ou autres ressources) allou�e pour t n'est jamais lib�r�e.
    Citation Envoy� par r0d
    Citation Envoy� par JolyLoic
    S'il est bien programm�, cette tentative de construction n'aura pas allou� de resosurces sans les lib�rer.
    Si j'ai bien compris, si on a une construction du type:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    MaClasse::MaClasse(int iValue)
    {
       m_aiMonTableau = new int(iValue);
       try
       {
          m_pMonObjet->Connect(); // connection à une bdd par exemple
       }
     
       catch (CMyConnectionException* pEx)
       {
          pEx->ReportError();
       }
    }
    On risque d'allouer le tableau m_aiMonTableau alors que la classe n'est pas construite? (dans le cas o� le connect() renvoie une exception)
    Il faudrait alors rajouter un delete[] m_aiMonTableau; dans le catch. C'est �a?
    Oui et non. Oui le probl�me est bien celui l�. Non, sa r�solution ne passe pas par un bloc catch, mais plut�t par du RAII : Par exemple, ici, au lieu d'utiliser un int* pour le tableau, utiliser un vector<int>.
    Ma session aux Microsoft TechDays 2013 : D�velopper en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage � la d�couverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'h�sitez pas � me contacter.

  8. #8
    r0d
    r0d est d�connect�
    Membre exp�riment�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 297
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 4 297
    Billets dans le blog
    2
    Par d�faut
    Merci pour ces pr�cisions
    Mais j'ai encore une question...
    Citation Envoy� par JolyLoic
    AMA = A mon avis.


    Citation Envoy� par JolyLoic
    Oui et non. Oui le probl�me est bien celui l�. Non, sa r�solution ne passe pas par un bloc catch, mais plut�t par du RAII : Par exemple, ici, au lieu d'utiliser un int* pour le tableau, utiliser un vector<int>.
    Qu'est-ce que le RAII? Et comment le vector se d�brouille-t-il pour s'auto-effacer en cas de probl�me dans le constructeur? Utilise-t-il un Observer?

  9. #9
    R�dacteur
    Avatar de Laurent Gomila
    Profil pro
    D�veloppeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    D�tails du profil
    Informations personnelles :
    �ge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par d�faut
    Le RAII : http://c.developpez.com/faq/cpp/?pag...POINTEURS_raii

    Apr�s avoir lu �a, tu devrais pouvoir r�pondre tout seul � ta question sur le vector.

  10. #10
    r0d
    r0d est d�connect�
    Membre exp�riment�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 297
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 4 297
    Billets dans le blog
    2
    Par d�faut
    Ok merci.

    Cet article est vraiment excellent. Il m'a permi de comprendre l'utilit� des smart pointers, en plus du RAII que je ne connaissais pas. Un idiome puissant et simple finalement. D'ailleurs, pourquoi n'est-ce pas un design pattern?

  11. #11
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    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 296
    Par d�faut
    Idiome et design pattern sont deux choses proches arriv�es � peu pr�s au m�me moment (je parle d'histoire) et ayant donc ... des noms diff�rents.
    Aujourdh'ui, on retient (moi du moins) en g�n�ral qu'un idiome est un petit DP sp�cialis� pour un langage. Je trouve aussi qu'en C++, on parle plus volontier d'idiomes que de patterns pour des choses comme le RAII, l'enveloppe-lettre, ...

    Quant au RAII, son �quivalent dans d'autres langages que je ne citerai pas, est le dispose-pattern ... (Ils s'inscrivent tout deux dans le cadre plus g�n�ral de la lib�ration d�terministe de ressources)
    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...

  12. #12
    r0d
    r0d est d�connect�
    Membre exp�riment�

    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    4 297
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 4 297
    Billets dans le blog
    2
    Par d�faut
    merci � tous, j'ai appris beaucoup gr�ce � vous. Et bien que j'aie encore tout un tas de questions concernant la conception, je vais clore ce topic et continuer mon investigation tranquillement. Et puis je vais me remettre � l'UML, que je n'ai plus pratiqu� depuis l'universit�

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. syntaxe, init membre sans constructeur par d�faut
    Par Ghurdyl dans le forum D�buter
    R�ponses: 3
    Dernier message: 17/07/2009, 15h33
  2. [VB6]Déclaration d'un Constructeur Spécialisé
    Par TagadaTsoin dans le forum VB 6 et ant�rieur
    R�ponses: 21
    Dernier message: 26/05/2004, 14h09
  3. Capture d'exception dans un constructeur
    Par declencher dans le forum Composants VCL
    R�ponses: 8
    Dernier message: 03/02/2004, 12h52
  4. [CR7] Erreur CanNot initalize OLE
    Par elifqaoui dans le forum SAP Crystal Reports
    R�ponses: 4
    Dernier message: 17/07/2003, 22h03
  5. pb constructeurs classes d�rivant classe abstraite
    Par Cornell dans le forum Langage
    R�ponses: 2
    Dernier message: 10/02/2003, 19h02

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