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 :

constructeur et = (avec auto_ptr)


Sujet :

C++

  1. #1
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut constructeur et = (avec auto_ptr)
    Bonjour,
    je ne comprend pas pourquoi ce code ne fonctionne pas
    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
    class Base
    {
    public:
    	virtual void DoIt()
    	{};
    };
     
    class TTest: public Base
    {};
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    	{
    		std::auto_ptr<TTest> test = new	TTest(); // (1)
    	}
    	getchar(); 
    	return 0;
    }
    Le programme plante lors de la libération de l'instance de TTest, lorsque le bloc mémoire est libéré (une assertion en debug : _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)); ). Ma classe n'a pas de destructeur virtuel, mais c'est sur le bon type que la libération doit s'effectuer.
    Pourtant en changeant (1) par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::auto_ptr<TTest> test ( new TTest() );
    il n'y a plus de problème. Il me semblait que ces deux versions étaient équivalentes .

  2. #2
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Les deux versions ne sont pas 100% équivalentes, mais dans le cas où les deux compilent, elles devraient avoir le même comportement.

    Par contre, on devrait justement être dans le cas où le code ne compile pas, puisque le constructeur d'auto_ptr est déclaré explicit.
    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.

  3. #3
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut
    en effet le constructeur est bien marqué explicit. Mais il me semble qui si ce n'était pas le cas dans :
    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
    25
    26
    27
    28
    29
    30
    class TInt
    {
    private:
    	int m_int;
    public:
    	TInt( int i = 0):m_int(i) //(1)
    	{} 
    	TInt( const TInt & Other ):m_int(Other.m_int) //(2)
    	{}	
    	TInt & operator = (const TInt & Other) //(3)
    	{
    		m_int = Other.m_int;
    		return *this;
    	}
    //	TInt & operator = (int i)   // (4)
    //	{
    //		m_int = i;
    //		return *this;
    //	}	
    };
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    	{
    		TInt Int1(1), Int2 = 2, Int3;
    		Int3 = 3;
    	}
    	getchar(); 
    	return 0;
    }
    même sans optimisation Int1 et Int2 n'utiliseront que (1), alors que Int3 sera construit par (1) puis sera affecté par (3) après que l'entier fut converti implicitement par (1) (ou directement (4) si il est défini ).
    En revanche lorsque "explicit" est utilisé Int2 ne peut être construit de la sorte et Int3 ne peut être assigné que si (4) est défini (ou si on utilise explicitement TInt(3)).
    Pour en revenir à mon auto_ptr, ne pouvant utiliser le constructeur explicit, il doit utiliser celui-ci (VS 2005 (c) )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()
    		{	// construct by assuming pointer from _Right auto_ptr_ref
    		_Ty **_Pptr = (_Ty **)_Right._Ref;
    		_Ty *_Ptr = *_Pptr;
    		*_Pptr = 0;	// release old
    		_Myptr = _Ptr;	// reset this
    		}
    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template<class _Ty>
    	struct auto_ptr_ref
    		{	// proxy reference for auto_ptr copying
    	auto_ptr_ref(void *_Right)
    		: _Ref(_Right)
    		{	// construct from generic pointer to auto_ptr ptr
    		}
     
    	void *_Ref;	// generic pointer to auto_ptr ptr
    	};
    prenant le pointeur que je lui passe pour un _Ty ** alors que c'est un _Ty *, d'où le plantage .

  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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Normalement, il n'a pas le droit. D'ailleurs j'ai testé avec VS2008, et il fait bien un message d'erreur à la compilation.
    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
    Membre confirmé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Points : 546
    Points
    546
    Par défaut
    Sous VS 2005 ni auto_ptr(auto_ptr_ref<_Ty> _Right) ni auto_ptr_ref(void *_Right) ne sont déclarés explicit (peut être qu'ils le sont sous 2008), seul auto_ptr(_Ty *_Ptr = 0) l'est. En debug, il passe bien par ces deux constructeurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    004114B4 E8 EB FC FF FF   call        std::auto_ptr_ref<TTest>::auto_ptr_ref<TTest> (4111A4h) 
    004114B9 8D 4D F8         lea         ecx,[test] 
    004114BC E8 07 FC FF FF   call        std::auto_ptr<TTest>::auto_ptr<TTest> (4110C8h)
    En tout cas j'utiliserais toujours un constructeur explicite pour initialiser mes std::auto_ptr avec un pointeur, parce que sinon .

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 20/04/2014, 15h56
  2. Réponses: 2
    Dernier message: 22/03/2012, 12h24
  3. pimpl avec auto_ptr
    Par yan dans le forum Langage
    Réponses: 4
    Dernier message: 04/05/2010, 16h45
  4. Réponses: 7
    Dernier message: 30/09/2004, 12h55
  5. [Constructeur]Pb avec la surcharge d un constructeur
    Par cmoulin dans le forum Langage
    Réponses: 3
    Dernier message: 26/04/2004, 09h29

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