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 :

Déclarer un membre non-copyable


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut Déclarer un membre non-copyable
    Bonjour,

    J’ai une classe (non copiable). Dedans cette classe, il y a un gros tableau, qui est un std::vector. Je voudrais m’assurer que ce vecteur n’est pas copié implicitement (par erreur, soit parce qu’on le passe en paramètre de fonction par copie et pas par ref).

    J’aimerai donc faire un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class A
    {
    private:
        noncopyable std::vector<Data> m_data;
    …
    public:
        noncopyable std::vector<Data>& data() { return m_data; }}
    Y a-t-il une solution standard à ce problème ?

    Je suis parfaitement conscient que si on veut copier le vecteur, on le copiera. L’idée est plutôt ici de détecter à la compilation une copie accidentelle (operator=, passage de paramètre…), qui me plomberait mes perfs. La copie explicite étant toujours possible via itération sur le vecteur.

  2. #2
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 293
    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 293
    Billets dans le blog
    2
    Par défaut
    Comme ça à chaud et sans plus de détails, je dirais que la solution est l'encapsulation: empêcher l'accès au conteneur, et se débrouiller pour mettre de code qui utilise ce conteneur à l'intérieur de la classe qui le possède.

  3. #3
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Par défaut
    A priori je verrais bien quelque chose comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class A
    {
    private:
        std::vector<Data> m_data;
    …
    public:
        std::vector<Data>::iterator begin() { return m_data.begin(); }
        std::vector<Data>::const_iterator begin() const { return m_data.begin(); }
     
        std::vector<Data>::iterator end() { return m_data.end(); }
        std::vector<Data>::const_iterator end() const { return m_data.end(); }}

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 149
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    Ne peux-tu pas passer le vector en private et ne fournir qu'un getter const& ?
    C'est cheap, mais ça peut être un compromis simple.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    BousK : j’ai déja mon vecteur en membre privé et l’accesseur en const ref, mais ça ne change rien : si je l’expose tel quel, je ne peux pas empêcher qu’on le copie par erreur.

    r0d & cob59 : yep, ça marche. Mais ça m’oblige à redéfinir toute l’interface de std::vector, juste pour ça. Je cherchais justement une solution qui m’évite cela. À la limite, je peux surcharger l’opérateur ->, mais ça ne me satisfait pas vraiment.

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

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 293
    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 293
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par white_tentacle Voir le message
    r0d & cob59 : yep, ça marche. Mais ça m’oblige à redéfinir toute l’interface de std::vector, juste pour ça. Je cherchais justement une solution qui m’évite cela. À la limite, je peux surcharger l’opérateur ->, mais ça ne me satisfait pas vraiment.
    La solution que je proposais est différente de celle de cob. Moi je propose de masquer totalement l'existence du vecteur (donc pas d'accesseurs, contrairement à ce que propose cob). Ce qui implique que tout le code qui utilise ce vecteur sera dans la classe qui le possède.
    Par contre je ne sais pas si c'est applicable dans le contexte de ton programme.

  7. #7
    Membre chevronné

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

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Par défaut
    T'es-t-il possible de rendre Data non copiable ? Si oui, tu peux avoir un std::vector fonctionnel mais non copiable, à la seule condition que ton constructeur de mouvement soit déclaré noexcept (pour des raisons subtiles, mais bien expliquées ici) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    struct Data {
        Data() = default;
        Data(const Data&) = delete;
        Data(Data&&) noexcept { ... }
        Data& operator=(const Data&) = delete;
        Data& operator=(Data&&) noexcept { ... return *this; };
    };
    Sinon tu peux wrapper Data dans une classe proxy qui elle est non copiable.

Discussions similaires

  1. Réponses: 1
    Dernier message: 26/09/2007, 17h16
  2. Boost thread avec fonction membre non statique.
    Par Klaim dans le forum Boost
    Réponses: 2
    Dernier message: 11/08/2007, 02h58
  3. [C#][Langage]Comment déclarer un membre obsolète
    Par DonkeyMaster dans le forum C#
    Réponses: 4
    Dernier message: 23/01/2007, 17h59
  4. [MySQL] Information membre non inscrite dans la base de donnée
    Par Margouillat974 dans le forum PHP & Base de données
    Réponses: 11
    Dernier message: 28/09/2006, 19h21
  5. Déclarer un entier non-signé [PHP]
    Par Bouillou dans le forum Langage
    Réponses: 2
    Dernier message: 17/02/2006, 16h46

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