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 :

Constructeur & shared_from_this


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de GrosLapin
    Homme Profil pro
    Ingénieur et Etudiant
    Inscrit en
    Avril 2013
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur et Etudiant

    Informations forums :
    Inscription : Avril 2013
    Messages : 47
    Par défaut Constructeur & shared_from_this
    Bonjour à tous,

    Débutant avec les pointeurs intelligents (vieux motard que jamais ) j'ai rencontrer un problème qui a soulevé plusieurs questions.

    Je vous pose le contexte de maniérè très simplifié : Je suis en train de créer un petit "tower défense" (dans un but pédagogique) qui contient des Cases qui contiennent des "éléments de jeu" (dans une collection quelconque de weak_ptr puisque la Case ne souhaite pas gérer la mémoire mais uniquement pouvoir regarder s'il y a des gens dedans). Une case est dite "occupé" si il y a au moins un élément de jeu dedans. J'ai ensuite créé une Tour qui est un élément de jeu et qui prend en paramètre du constructeur une case.
    Et voila, le drame arrive :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Tour(Case& maCase)
    {
        [...]
        maCase.addElementJeu(shared_from_this());
    }
    Et c'est le Bad_Weak_Ptr \o/

    Un coup de google, on me dit que mon objet est pas completement construit et que je peux pas faire ça... Ok. Bon pas dramatique je vais faire une fonction statique [type de retour à réfléchir] CreerTour(Case&), un constructeur en protected et j'aurais ce que je veux.

    Cependant j'ai deux questions que j'arrive pas résoudre :
    1. Comment la fonction shared_from_this sait que j'ai pas fini le constructeur, je veux dire, elle vient d'une classe mère qui devrait être initialisé avant de rentrer dans le constructeur, comment elle sait que l'objet est pas fini d’être construit ?
    2. Qu'est ce que ça veux dire ne pas être complétement construit ? Qu'est ce que mon objet a concrètement de plus entre la dernière ligne de mon constructeur et le moment ou il est construit ?
    3. Ce que je faisais avant (quand j'utilisais pas les qqch_ptr) aurait était de faire maCase.addElementJeu(this) je suppose qu'il doit aussi y avoir un problème d'objet mal construit mais je vois pas lequel...

    Et oui ça fait trois questions \o/

    Si vous pouvez m'éclairer, je suis preneur

    GrosLapin

  2. #2
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Est-ce que ton objet Tour est instancié dans un shared_ptr<Tour> ?

  3. #3
    Membre éclairé Avatar de GrosLapin
    Homme Profil pro
    Ingénieur et Etudiant
    Inscrit en
    Avril 2013
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur et Etudiant

    Informations forums :
    Inscription : Avril 2013
    Messages : 47
    Par défaut
    J'ai pas mon code sous les yeux mais ça je crois pas.
    En version minimaliste :
    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
     
    using namespace std;
     
    struct Tour;
    struct Case
    {
        vector<weak_ptr<Tour>> vecTour;
        void addTour(weak_ptr<Tour> wpT) { vecTour.push_back(wpT);}
    };
     
    struct Tour : public enable_shared_from_this<Tour>
    {
        Tour (Case& uneCase)
        {
            uneCase.addTour(shared_from_this());
        }
    };
     
    int main ()
    {
        Case uneCase;
        Tour uneTour(uneCase);  // call un std::bad_weak_ptr
        shared_ptr<Tour> test = make_shared<Tour>(uneCase); // call un std::bad_weak_ptr
    }
    J'ai testé aussi en le mettant dans un shared_ptr comme tu le suggères mais ça change rien

    Ps : Ceci étant à part si j'ai loupé quelque chose d’énorme (ce qui peut tout à fait être le cas) je cherche plus des réponses aux questions qu'une solution pour mon code ^^

  4. #4
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Hello,

    Si je dis pas de conneries, shared_from_this ne doit pas être appelé depuis le constructeur.
    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
    using namespace std;
     
    struct Tour;
    struct Case {
    	vector<weak_ptr<Tour>> vecTour;
    	void addTour(weak_ptr<Tour> wpT) { vecTour.push_back(wpT);}
    };
     
    struct Tour : public enable_shared_from_this<Tour> {
    	static shared_ptr<Tour> create(Case& c) {
    		auto t = make_shared<Tour>();
    		c.addTour(weak_ptr<Tour>(t));
    		return t;
    	}
     
    private:
    	Tour ()	{ }
    };
     
    int main () {
        Case uneCase;
        auto tour = Tour::create(uneCase);
    }
    (Le nom "Case" est à éviter : risque de confusion avec le mot-clef)

  5. #5
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 766
    Par défaut
    un petit lien peut-être utile : Checked delete

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    309
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 309
    Par défaut
    Citation Envoyé par Iradrille Voir le message
    Si je dis pas de conneries, shared_from_this ne doit pas être appelé depuis le constructeur.
    La partie importante est que shared_from_this ne peut etre appele que sur un objet qui est deja géré par un shared_ptr (c'est la creation de ce shared_ptr qui va initialiser le weak_ptr a l'interieur du enable_shared_from_this).

    Or dans le constructeur, l'objet n'est pas encore géré par un shared_ptr, donc son weak_ptr n'est pas initialisé, d'où l'erreur que tu reçois.

    Mais de façon générale, tu devrais eviter les shared_ptr autant que faire ce peux. La majorité du temps, tu devrais pouvoir trouver qui "possède" un certain objet. Dans ton cas, il me semble qu'il serait naturelle que la case possède la Tour, et donc aie un unique_ptr.

  7. #7
    Membre éclairé Avatar de GrosLapin
    Homme Profil pro
    Ingénieur et Etudiant
    Inscrit en
    Avril 2013
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur et Etudiant

    Informations forums :
    Inscription : Avril 2013
    Messages : 47
    Par défaut
    Merci pour vos réponses et désolé pour mon temps de réponse, j'avais pas le net

    @Iradrille
    Si je dis pas de conneries, shared_from_this ne doit pas être appelé depuis le constructeur.
    Yep, effectivement, mais ce que je comprends pas c'est comment il sait que je suis encore dans le constructeur ?

    @foetus
    Je suis pas sur d'avoir bien compris :'( l'astuce du checked delete c'est pour quand on ne connais pas encore le type (déclaration incomplète) si j'ai bien compris ton lien. Ca voudrais dire qu'on ne connait pas la taille d'un type dans son constructeur ?

    @TropMDR
    Mais de façon générale, tu devrais eviter les shared_ptr autant que faire ce peux.
    Le problème que j'ai avec les unique_ptr c'est : Comment permettre à une autre classe d'avoir le droit de regarder la ressource sans utiliser un pointeur nu (On m'a dit que le but des pointeurs intelligents était de pouvoir se passer des pointeurs nus)

    GrosLapin

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 14/06/2010, 10h58
  2. [VB6]Déclaration d'un Constructeur Spécialisé
    Par TagadaTsoin dans le forum VB 6 et antérieur
    Réponses: 21
    Dernier message: 26/05/2004, 14h09
  3. Capture d'exception dans un constructeur
    Par declencher dans le forum Composants VCL
    Réponses: 8
    Dernier message: 03/02/2004, 12h52
  4. pb constructeurs classes dérivant classe abstraite
    Par Cornell dans le forum Langage
    Réponses: 2
    Dernier message: 10/02/2003, 19h02

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