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

Langage C++ Discussion :

Assignation implicite : besoin d'explication


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut Assignation implicite : besoin d'explication
    Bonjour,

    j'ai fait une classe générique Number<T> pour avoir mes propres objets Double, Float, Integer, etc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    template<typename T>
    class Number<T>
    {
        private:
            T _real;
        public:
            Number(T const&);
            Number(Number<T>const&);
            Number<T>& operator=(Number<T>const&);
    };
    L'attribut _real permet de stocker la valeur du nombre. J'ai une question à propose de ce bout de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Number<double> a = 1.0;
    a = 2.0;
    A la première ligne, il y a un appel implicite au premier constructeur de ma classe : je n'ai pas de problème avec ça. Par contre, je ne comprends pas pourquoi la seconde ligne fonctionne. Elle est importante car elle me permet ensuite de surcharger les opérateurs "+,-,*,/" de manière efficace (je suis aussi rapide que les opérations classiques en exploitant le tag -O3 de g++).

    Voilà, si quelqu'un pourrait m'éclairer sur ce point et me dire si ce comportement est dans la norme ou si c'est propre à g++.

    Merci

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    188
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 188
    Par défaut
    tu as un appelle implicite a ton premier constructeur afin de créer un Number<double>const depuis le double 2.0.

    tu peux mettre des logs dans tes constructeurs pour voir ce qui ce passe:
    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
     
    template<typename T>
    class Number
    {
    private:
        T _real;
    public:
        Number(T const& n){
    	std::cout << "constructeur de base avec n = " << n << std::endl;
    	_real = n;
        }
     
        Number(Number<T>const& other){
    	std::cout << "constructeur de recopie avec other._real = " << other._real << std::endl;
    	_real = other._real;
        }
     
        Number<T>& operator=(Number<T>const&other){
    	std::cout << "op affect avec other._real = " << other._real << std::endl;
    	_real = other._real;
        }
    };
     
    int main(int argc, char* argv[])
    {
        Number<double> a = 1.0;
        a = 2.0;
     
        return 0;
    }
    ce qui donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    constructeur de base avec n = 1
    constructeur de base avec n = 2
    operateur d'affectation avec other._real = 2

  3. #3
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Bonjour,

    merci pour ta réponse atttchoum.
    Je vais vérifier.

  4. #4
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Merci atttchoum c'était effectivement ce qui se passait!

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Dans ce cas, c'est l'objectif recherché, mais sinon tu as explicit qui permet d'éviter ces conversions implicites :explicit Number(T const&) qui génère ensuite une erreur lors des affectations.
    Ceci dit, j'ai un peu tendance à me méfier des conversions implicites et préfère rajouter une fonction spécifique lorsque j'en ai besoin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template<typename T>
    class Number<T>
    {
        private:
            T _real;
        public:
            explicit Number(T const&);
     
            Number<T>& operator=(Number<T>const&);
            Number<T>& operator=(T);
    };
    Enfin, je ne vois pas l'intérêt d'un opérateur d'affectation (Quand dois-je définir l'opérateur d'affectation ?) et d'un constructeur de copie (Quand dois-je définir un constructeur par copie ?) qui font ce que fait celui que fait par défaut le compilateur.

  6. #6
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Bonjour 3DArchi,

    j'ai découvert le mot-clé explicit depuis peu en regardant la manière dont est implémenté Blitz++. Si ma mémoire est bonne, en testant le mot-clé explicit dans l'exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Number<double> a(1.0);
    a = 2.0;
    l'appel au constructeur explicit Number<double>(double const &) est malgré tout effectué. Je vais vérifié pour être sûr.

    Comme tu le suggères, j'ai moi aussi préféré la surcharge
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Number<T> operator=(T const&);
    plutôt que de laisser un appel implicite à un constructeur. J'ai pensé que l'opération serait plus rapide ainsi, peut-être à tort.

    Si je lis correctement
    Enfin, je ne vois pas l'intérêt d'un opérateur d'affectation (Quand dois-je définir l'opérateur d'affectation ?) et d'un constructeur de copie (Quand dois-je définir un constructeur par copie ?) qui font ce que fait celui que fait par défaut le compilateur.
    tu écris que ma classe pourrait simplement s'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    template<typename T>
    class Number<T>
    {
    private:
        T _real;
    public:
        Number(T const&);
        Number<T> operator=(T const&);
    };
    et que je pourrais tout de même écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Number<double> a = 1.0;
    Number<double> b = 2.0;
    a = b;
    Est-ce bien cela? Dans ce cas, si une autre classe hérite de Number<double>, pourrais-je quand même appelé les constructeurs appelés par défaut par le compilateur? Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include "Number.hpp"
    class AnotherClass : private Number<double>
    {
    private:
        // ... des attributs ...
    public:
        AnotherClass(AnotherClass const&);
        // .... des méthodes ...
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    AnotherClass::AnotherClass(AnotherClass const& param)
    :Number<double>(param)
    {
        ;
    }

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

Discussions similaires

  1. besoin d'explication sur le c++
    Par poporiding dans le forum MFC
    Réponses: 13
    Dernier message: 17/12/2005, 18h01
  2. Besoin d'explications sur un bout de code
    Par zizitop dans le forum C
    Réponses: 7
    Dernier message: 26/04/2005, 14h51
  3. [C#] J'aurais besoin d'explication
    Par Roach- dans le forum Windows Forms
    Réponses: 18
    Dernier message: 10/03/2005, 16h00
  4. Besoin d'explications sur float et l'élasticité !
    Par KneXtasY dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 14/01/2005, 15h15
  5. [Foreign Key] Besoin d'explication.
    Par Andry dans le forum Débuter
    Réponses: 4
    Dernier message: 28/05/2003, 11h34

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