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 :

Initialisation uniforme et héritage


Sujet :

Langage C++

  1. #1
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut Initialisation uniforme et héritage
    Bonjour,

    Le code suivant compile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct test {
        int i, j;
    };
     
    int main() {
        test t{0,1};
        return 0;
    }
    ... alors que celui-ci ne compile pas (gcc 4.7 et clang 3.3 sont d'accord) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    struct base {};
     
    struct test : /* private */ base {
        int i, j;
    };
     
    int main() {
        test t{0,1}; // erreur: aucun constructeur ne correspond
        // note: candidats possibles:
        // note:  test()
        // note:  test(const test&)
        // note:  test(test&&)
        return 0;
    }
    J'ai rencontré ce problème dans un cas où base ne contient vraiment aucune donnée et fonction membre, et ne sert qu'à fournir des typedefs et autres constantes de compilations. J'ai de nombreuses structures comme test, et j'aimerai bien éviter d'avoir à me farcir un constructeur trivial pour chacune d'entre elle... Autrement dit, je sais qu'une solution est d'ajouter test(int i_, int j_) : i(i_), j(j_) {} dans test, mais c'est pénible (à la fois à écrire et à maintenir).

    Connaissez-vous un moyen pour ré-activer l'initialisation uniforme dans ce cas là ?

    Merci.

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

    test t{0,1}; (C++11) est strictement équivalant à test t(0,1);.
    Personnellement, je préfère le seconde méthode car la première ne marche pas avec les version antérieur au C++11.

    A ne pas confondre avec :
    Qui fait exactement ce que tu souhaites.

    En C++11, ça utilise peut être le constructeur avec une liste d'initialisation (?).
    Et pour les version antérieur, je pense que ça convertit {0,1} en un test puis que ça utilise un constructeur par copie.

    Je n'ai pas vraiment le temps de vérifier cela, à tester.

    Pense aussi à mettre des majuscules pour tes noms de types .

  3. #3
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Pardon, j'aurais dû poser ma question initiale autrement. Le problème est aussi visible avec le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct base {};
     
    struct test : base {
        int i, j;
    };
     
    void foo(test t) {}
     
    int main() {
        foo({0,1}); // erreur
        return 0;
    }
    C'est précisément dans cette situation que j'ai découvert la chose (et c'est aussi là que tu vois tout l'intérêt de cette syntaxe par rapport au C++03 : pas besoin d'expliciter le type construit, le compilateur l'infère tout seul).

    J'ai pris le temps de regarder la norme, et en fait j'ai trouvé la réponse : non, c'est impossible... Cette syntaxe ne fonctionne que :
    1. si les éléments de la liste sont compatibles avec un des constructeurs de la classe,
    2. ou si la classe est un agrégat, auquel cas chacun des membres est initialisé dans l'ordre de leur déclaration.

    Or, dans la définition de ce qu'est un agrégat ([dcl.init.aggr]), il est écrit explicitement que la classe ne doit pas avoir de classe de base... C'est donc cuit. Je comprends l'idée si la classe de base a elle aussi des membres à initialiser, mais moralement c'est dommage que ça ne fonctionne pas pour une classe de base "vide", qui ne gène en rien l'opération. Du coup j'ai écrit un message sur le google group ISO C++ pour savoir s'il est possible de faire évoluer ça dans une version future du langage.

    PS: Quant à ta remarque sur les majuscules pour les types, désolé je préfère les minuscules et underscores. Ce n'est qu'une convention parmi tant d'autres ([taquinerie]j'ai de mon côté boost et la bibliothèque standard, tout de même [/taquinerie]), et on pourrait en discuter pendant longtemps, et je crois qu'il n'existera jamais de consensus à ce sujet.

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    En effet ça ne marche pas ce qui est assez dommage.
    Même avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Base{};
     
    struct Test : Base{
            int i;
            int j;
    };
     
    int main(void)
    {
            Base b;
            Test t = {b, 5,6};
            return 0;
    }
    C'est vrai que c'est assez bête.

    Bon, tu n'as pas d'autres choix que d'utiliser une liste d'initialisation du C++11.

    Citation Envoyé par Kalith Voir le message
    PS: Quant à ta remarque sur les majuscules pour les types, désolé je préfère les minuscules et underscores. Ce n'est qu'une convention parmi tant d'autres ([taquinerie]j'ai de mon côté boost et la bibliothèque standard, tout de même [/taquinerie]), et on pourrait en discuter pendant longtemps, et je crois qu'il n'existera jamais de consensus à ce sujet.
    Disons que c'est juste qu'une grande majorité de devs C++ font ainsi et que c'est plus facile de se repérer entre types et variables

Discussions similaires

  1. Héritage initialisation membre const
    Par themadmax dans le forum C++
    Réponses: 7
    Dernier message: 26/05/2011, 15h31
  2. Question héritage et initialisation
    Par loudo dans le forum Langage
    Réponses: 4
    Dernier message: 15/05/2009, 12h02
  3. Initialisation de XMLModule
    Par Sylvain Leray dans le forum XMLRAD
    Réponses: 10
    Dernier message: 01/04/2003, 10h08
  4. initialisation Directinput avec delphi
    Par Madmaxx dans le forum DirectX
    Réponses: 1
    Dernier message: 21/02/2003, 17h37
  5. Héritage entre Forms
    Par BarBal dans le forum Composants VCL
    Réponses: 7
    Dernier message: 29/08/2002, 17h44

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