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 :

durée de vie


Sujet :

C++

  1. #1
    Membre du Club
    Homme Profil pro
    Collégien
    Inscrit en
    Février 2016
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Collégien
    Secteur : Alimentation

    Informations forums :
    Inscription : Février 2016
    Messages : 20
    Points : 46
    Points
    46
    Par défaut durée de vie
    Bonsoir

    j'ai une question un peu idiote.
    J'ai une classe qui possède en public différentes fonctions pour construire un objet. Voici un extrait du code
    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
    31
    32
    33
    34
     
    //public
    TypeBien* TypeManager::GetTypeById(const size_t id){
        TypeBien* returnMe = NULL;
        std::map<size_t,std::unique_ptr<TypeBien> >::iterator it = m_ListeTypes.find(id);
        if(it != m_ListeTypes.end()){
            returnMe = it->second.get();
        }
        return returnMe;
    }
     
    TypeBien& TypeManager::CreateType(){
        TypeBien nouveauType(m_LastId,"");
        CreateType(nouveauType);
        m_LastId++;
        return nouveauType;
    }
     
    TypeBien& TypeManager::CreateType(const QString& libelle){
        TypeBien nouveauType(m_LastId,libelle);
        CreateType(nouveauType);
        return nouveauType;
    }
     
    //private
    void TypeManager::CreateType(TypeBien& nouveauBien){
        QString id = nouveauBien.GetId();
        QString libelle = nouveauBien.GetLibelle();
        QString requete = "INSERT INTO typebien (id,libelle) VALUES (" + id + "," + libelle + ")";
        m_Request.exec(requete);
        m_Request.finish();
     
        m_ListeTypes.insert(std::pair<size_t,std::unique_ptr<TypeBien> >(nouveauBien.GetIdNumber(),std::unique_ptr<TypeBien>(&nouveauBien)));
    }
    Mon but étant de ne pas recopier l'objet. C'est pour cela que je mets un pointeur dans ma map, et plus précisement un unique_ptr pour ne pas avoir à gérer leur destruction.
    Ma question est : ma fonction publique construit un objet dans la pile donc il devrait être supprimé à la fin du scope ? Je ne crois pas avoir fais une copie et pourtant quand je fais GetTypeById l'objet est toujours valide o_o.
    Vous pouvez m'expliquer ce qu'il se passe en mémoire s'il vous plait ?

    merci

  2. #2
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 469
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 469
    Points : 6 102
    Points
    6 102
    Par défaut
    Salut,

    Ta fonction TypeManager::CreateType(const QString& libelle) crée un objet automatique nouveauType dont le destructeur sera appelé à la fin de l'appel de cette fonction.
    Du coup, cette fonction retourne une référence vers un objet qui n'existe plus, ce qui entraînera tôt ou tard un crash du programme.

    Entre temps, cette fonction appelle TypeManager::CreateType(TypeBien& nouveauBien) qui met l'adresse de ton objet nouveauType dans un std::unique_ptr d'un std::map<size_t,std::unique_ptr<TypeBien>>.
    Quand le destructeur de ce std::unique_ptr sera appelé, le programme essaiera de détruire l'objet nouveauType déjà détruit, ce qui fera crasher le programme, s'il n'a pas déjà crashé avant à cause de l'autre erreur décrite ci-avant.

    Pour gérer facilement la mémoire, parmi les variables qui contiennent l'adresse d'un objet, il faut distinguer clairement les variables qui gèrent la destruction de l'objet. Pour cela, il y a une convention simple :
    • std::unique_ptr : La variable doit détruire l'objet.
    • std::shared_ptr : Un ensemble de variables partagent un objet. On ne sait pas laquelle sera détruite en dernier, mais la dernière détruite devra détruire l'objet.
    • Pointeur, référence ou std::reference_wrapper : La variable ne doit pas détruire l'objet.

    Cela vaut aussi pour les types des paramètres des fonctions et les types de retour.

    Les pointeurs nus qui sont responsables de la destruction de l'objet son dangereux, ce qui doit être pallié par de la documentation.

    Si on applique cette règle à TypeManager::CreateType(TypeBien& nouveauBien), cela peut donner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void TypeManager::CreateType(std::unique_ptr<TypeBien> nouveauBien){ // passage par valeur volontaire
        assert(nouveauBien);
        if(!nouveauBien)
            throw std::invalid_argument("TypeManager::CreateType(std::unique_ptr<TypeBien> nouveauBien): argument must not be null.");
        QString id = nouveauBien->GetId();
        QString libelle = nouveauBien->GetLibelle();
        QString requete = "INSERT INTO typebien (id,libelle) VALUES (" + id + "," + libelle + ")";
        m_Request.exec(requete);
        m_Request.finish();
     
        m_ListeTypes.insert(std::pair<size_t,std::unique_ptr<TypeBien> >(id,std::move(nouveauBien)));
    }
    Cela dit, le code est étrange.
    • TypeManager::CreateType() incrémente m_LastId, mais pas TypeManager::CreateType(const QString& libelle). Pourtant, dans ton tableau associatif, la clé est l'id.
    • Pourquoi un std::map<size_t,std::unique_ptr<TypeBien>> au lieu d'un std::vector<QString> ? L'indice serait l'id et la valeur serait le libellé.
    • Dans ton programme, quel est le rôle de TypeBien ? A quel besoin répond-il ?

Discussions similaires

  1. Durée de vie d'une session
    Par dbass dans le forum Langage
    Réponses: 8
    Dernier message: 21/03/2006, 19h38
  2. [Cookies] durée de vie de l'objet
    Par ozzmax dans le forum Langage
    Réponses: 13
    Dernier message: 13/01/2006, 21h38
  3. [savoir] durée de vie d'un PC?
    Par afrikha dans le forum Composants
    Réponses: 20
    Dernier message: 24/10/2005, 13h28
  4. [AS2] durée de vie d'une classe (extends movieclip)
    Par ooyeah dans le forum ActionScript 1 & ActionScript 2
    Réponses: 4
    Dernier message: 23/07/2005, 13h33
  5. prob de durée de vie de IDvdGraphBuilder
    Par Chaksss dans le forum DirectX
    Réponses: 11
    Dernier message: 30/12/2004, 16h09

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