Pb constructeur par déplacement

Problème : Le constructeur par déplacement n'est jamais appelé

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour à tous, Pour satisfaire ma curiosité j'ai voulu testé une classe très simple ayant un constructeur de copie et un constructeur par déplacement.Et dans le main j'ai crée deux instances de cette classe.A la première j'ai affecté à mon premier objet un autre objet du même type afin d'utiliser le constructeur de copie et j'ai affecté à mon deuxième objet un objet temporaire afin d'utiliser le constructeur par déplacement. Voici le code :

Testun.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#ifndef TESTUN_H_INCLUDED
#define TESTUN_H_INCLUDED
class Testun
{
  public :
  Testun(int a);
  Testun(Testun &&t) ;
  Testun(const Testun &t);
  ~Testun();
   private :
   int m_a;
};


#endif // TESTUN_H_INCLUDED

Testun.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include "Testun.h"
#include <iostream>
Testun::Testun(int a):m_a(a)
{

}
Testun::Testun(Testun &&t)
{
  std::cout<<"Appel constructeur par déplacement"<<std::endl;
}
Testun::Testun(const Testun &t)
{
  std::cout<<"Appel constructeur de copie"<<std::endl;
}
Testun::~Testun()
{

}

main.cpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#include <iostream>
#include "Testun.h"
using namespace std;

int main()
{

    Testun a=Testun(9); // Ici le constructeur par déplacement devrait être appelé ,non ?
    Testun b=a;
    return 0;
}

Le problème vient du fait que le constructeur par déplacement n'est jamais appelé alors qu'un objet temporaire est pourtant affecté à mon objet a. Je remercie d'avance ceux qui pourront m'aider.Bonne journée à tous :) .

Edit : Je viens de me rendre compte que je me suis lamentablement trompé de forum en postant ce sujet,veuillez m'excuser :(

Édité par Octodex

+0 -0

Ajoutes un affichage dans ton constructeur qui prend un "int" en entrée. Tu vas comprendre ce qui se passe. Le compilateur est un gros malin.

First : Always RTFM - "Tout devrait être rendu aussi simple que possible, mais pas plus." A.Einstein

+1 -0
Auteur du sujet

Merci Ksass`Peuk pour ta réponse du coup j'obtiens

1
2
Constructeur
Constructeur de copie

Donc apparemment lorsque le compilateur voit :

1
Testun a=Testun(9)

Il va créer directement un seul objet identique à Testun(5) au lieu de passer par le constructeur par déplacement.C'est ça ?

+0 -0
Auteur du sujet

Merci de ta réponse cependant si le compilateur ne passe pas par le constructeur de déplacement pourquoi lorsque je fais :

1
Testun(Testun &&t)=delete;

J'ai une erreur du compilateur me disant qu'il ne peut pas faire :

1
Testun a=Testun()
+0 -0

Le remplacement de "constructeur de conversion + affectation par déplacement" par un simple constructeur de conversion est une optimisation, qui doit respecter la sémantique de la classe. Si le déplacement n'est pas autorisé, l'optimisation n'est pas autorisée.

HS : @jo_link_noir: je ne crois pas que ce soit un RVO. Je crois que c'est un cas particulier d'optimisation, autorisé explicitement dans la norme. (A priori, cf : http://en.cppreference.com/w/cpp/language/copy_initialization)

+2 -0
Auteur du sujet

Ah oui et une dernière question je viens de passer en mode release et là l'optimisation ne se fait pas et j'ai bien affiché dans ma console "Constructeur par déplacement" Le mode release n'est pas censé optimiser le plus possible le code ?

Édité par Octodex

+0 -0

Le mode release n'est pas censé optimisé le plus possible le code ?

Octodex

A vrai dire, il y n'a pas de mode "release" ou "debug" pour le compilateur. Ce sont sont justes deux cibles que ton IDE te propose, et chacune d'entre elles va compiler avec des options différentes.

Le plus souvent, on trouvera en release l'option -O2 (optimisation), et également l'option -s pour le linking (pas de table de symbole dans l'exécutable). Veille à ce qu'elles soient bien activées.

Édité par Olybri

+0 -0

Merci de ta réponse mais ces options étaient déjà activées.

Octodex

D'ailleurs je viens de tester avec GCC et Clang, et cette optimisation a lieu même sans l'option -O2. N'aurais-tu pas par mégarde laissé l'option -fno-elide-constructors dont jo_link_noir parlait plus haut ?

Sinon, peux-tu donner une liste complète des options activées ainsi que la version de ton compilateur ?

+0 -0
Auteur du sujet

N'aurais-tu pas par mégarde laissé l'option -fno-elide-constructors dont jo_link_noir parlait plus haut ?

Non je viens de vérifier et la ma version de mon compilateur est gnu gcc 5.2

Édité par Octodex

+0 -0

Testé sous Windows 8 avec GCC 5.2 également :

1
2
3
>g++ -std=c++14 code.cpp && a
Constructeur
Appel constructeur de copie

Donc soit tu as modifié quelque chose dans ton code, soit il y a une option qui fait foirer le truc. Difficile d'en dire plus pour ma part…

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte