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 :

Passer l'adresse classe à une autre


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 18 260
    Par défaut Passer l'adresse classe à une autre
    Bonsoir,

    Je souhaites passer en paramètre à une classe l'adresse de la classe créatrice (pour garder son parent). Les 2 classes sont autonomes.

    voici l'exemple :

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
    class FOURMI
    {
    public:
    FOURMI(FOURMILIERE pointeur)
    {
     
      _sleep(1);
      QTime time=QTime::currentTime();
      id=QTime().msecsTo(time);
    }
     
    int getId()
    {
      return id;
    }
     
    private:
    int id;
     
    };
     
    class FOURMILIERE
    {
    public:
    FOURMILIERE()
    {
      liste_fourmis=NULL;
      compteur=0;
    }
     
    void naissance()
    {
      ELEMENT *element=new ELEMENT;
      FOURMI *fourmi=new FOURMI(*this);
      element->fourmi=fourmi;
      element->next=liste_fourmis;
      liste_fourmis=element;
      ++compteur;
    }
     
     
    void liste()
    {
      ELEMENT *temp=liste_fourmis;
      while (temp!=NULL)
      {
        qDebug()<<temp->fourmi->getId();
        temp=temp->next;
      }
    }
     
    int count()
    {
      return compteur;
    }
     
    class ELEMENT
    {
    public:
      FOURMI *fourmi;
      ELEMENT *next;
    };
    ELEMENT *liste_fourmis;
    int     compteur;
    };
    Dans mon cas, je cherche à passer en paramètre lors le l'instanciation d'une "fourmi" dans ma méthode naissance l'adresse de la fourmilière. En fait comme parent.

    Ça fonctionne si j'enlève le *this de la ligne FOURMI *fourmi=new FOURMI(*this); et que je ne mets pas de paramètre dans mon constructeur.

    Mes deux classes sont autonomes, et je souhaites laisser cela comme cela.

    Je précise que je ne suis pas développeur de métier.

    Merci pour votre aide.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  2. #2
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Si tu initialises la fourmilière de ta fourmi uniquement dans le constructeur, tu peux la stocker en tant que membre référence dans fourmi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class FOURMI
    {
    public:
        FOURMI( FOURMILIERE & fourmiliere )
            : m_fourmiliere( fourmiliere )
        {
        }
     
        ...
     
    private:
        FOURMILIERE & fourmiliere;
    };
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Bonjour,

    Un pointeur ou une référence peut être défini sur un type incomplet, c'est à dire déclaré mais non défini.

    Il te suffit de déclarer à l'avance le type à pointer/référer. On parle de déclaration anticipée, ou en anglais on parle de forward declaration.

    Voici un exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    namespace exemple {
    class A; //pas d'accolade, c'est donc la déclaration d'un type A, qui sera une classe
     
    class B {
    private:
        A* pointeur;
    public:
        B(A* that) : pointeur(that) {}
    };
     
    //définition du type A
    class A {};
     
    }//exemple::
    Il est possible de ne pas définir le type déclaré dans le même en-tête.
    Il suffit que la définition soit visible au moment d'appeler la fonction ou classe.

    Il y a au moins un exemple dans la STL: <iosfwd> qui déclare les différents streams.
    Cela permet de déclarer les opérateurs << et >> pour une classe sans avoir à importer tout iostream.

  4. #4
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 18 260
    Par défaut
    Merci pour vos réponses. Tout cela me parait tordu pour stocker une adresse dans une variable.

    Ce que je souhaites :

    une fourmi appartient ou non à une fourmilière. Une fourmilière possède ou non des fourmis, les 2 classes sont indépendantes.
    Si je crée une fourmi depuis la classe fourmilière, je souhaites lui passer en paramètre l'adresse de l'instance de la fourmilière que je stockerais dans un champ parent.

    Je reprendrais ça à tête reposée.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  5. #5
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 18 260
    Par défaut
    Voici la solution que j'ai adopté.

    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
    35
    36
    37
    38
    39
    40
    41
     
    class FOURMI
    {
    public:
    FOURMI(void *adresse)
    {
      std::cout<<this<<"\n";
      std::cout<<"adr appelant "<<adresse<<"\n";
      parent=adresse;
    }
    FOURMI()
    {
      std::cout<<"pas de parametres"<<"\n";
    }
     
    private:
    void *parent=NULL;
    };
     
    class FOURMILIERE
    {
    public:
    FOURMILIERE()
    {
    }
     
    void naissance()
    {
      FOURMI *fourmi=new FOURMI(this);
    }
    };    
     
    int main()
    {
      FOURMI *fourmi=new FOURMI();
     
      FOURMILIERE *fourmiliere=new FOURMILIERE;
      fourmiliere->naissance();
      std::cout<<"fourmiliere "<<fourmiliere;
     
    }
    J'ai déclaré le parent en void. Ça compile et s’exécute.

    Si ce champ parent est destiné à être parent de plusieurs types d'objet, c'est adapté, on aura alors besoin d'un mécanisme pour pouvoir dissocier le type. Si le seul type possible de parent est FOURMILIERE, c'est pas grave de laisser en void, mais c'est pas propre et il faudra caster si nécessaire. Si je change le type de parent de void vers FOURMILIERE, ça ne compile pas. Je pense que c'est du au fait que la classe FOURMILIERE est déclaré après. Mais si j'inverse le positionnement des classes, je vais avoir le même problème car dans FOURMILIERE->naissance(), je crée une instance de FOURMI.

    Je peux laisser comme ça mais suis ouvert à tout commentaire ou proposition d'améliorations. Par contre, les exemples et explications m'ayant été fournis ne me parlent pas, je fais pas assez de C++ pour cela.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    void*? Je ne vois aucun intérêt à utiliser un void* ici.
    Si la fourmi ne peut pas changer de fourmilière au long de sa vie, il convient d'utiliser une référence. Si elle peut changer de fourmilière, un pointeur.

    Exemple avec référence:
    Code C++ : 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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    #include <iostream>
    #include <vector>
     
    class FOURMILIERE;
     
    class FOURMI
    {
    public:
    	explicit FOURMI(FOURMILIERE & parent) : parent(parent)
    	{
    		std::cout<<this<<"\n";
    		void* adresse = &parent;
    		std::cout<<"Fourmiliere parente "<<adresse<< std::endl;
    		parent=adresse;
    	}
    	//FOURMI() impossible si reference
    	//{
    	//	std::cout<<"pas de parametres"<<"\n";
    	//}
     
    private:
    	FOURMILIERE & parent;
    };
     
    class FOURMILIERE
    {
    public:
    	FOURMILIERE()
    	{
    	}
     
    	void naissance()
    	{
    		//S'il n'y a pas de virtualité, inutile d'utiliser l'allocation dynamique
    		fourmis.push_back(FOURMI(*this));
     
    		//Note: Si j'ai bien compris en C++11, la ligne au-dessus peut être remplacée par:
    		fourmis.emplace_back(*this);
    	}
     
    private:
    	std::vector<FOURMI> fourmis;
    };    
     
    int main()
    {
    	//FOURMI *fourmi=new FOURMI();
     
    	FOURMILIERE *fourmiliere=new FOURMILIERE;
    	fourmiliere->naissance();
    	std::cout<<"fourmiliere "<<fourmiliere;
     
    }


    ↓ Ça m'a l'air d'un gros fouillis dont je ne vois pas l'intérêt.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre averti
    Homme Profil pro
    Doctorant
    Inscrit en
    Novembre 2012
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 15
    Par défaut
    Bonjour,

    Si la classe fourmilière doit pouvoir instancier une fourmi elle doit avoir la visibilité sur la classe fourmi, les deux classes ne peuvent donc pas être indépendantes.
    L'utilisation d'une interface (exemple ici : Geniteur_fourmi) permettrait en revanche de gérer la provenance de la fourmi (si différente que fourmilière). Je propose la solution bien qu'elle me paraisse "bancale", plus de données sur la structure encadrante permettrait d'en élaborer une bien meilleur (idem pour référence à la place de pointeur pour _parent).

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    #include <stdlib.h>
    #include <iostream>
    #include <list>
    #include <string>
     
    class Geniteur_fourmi
    {
    public :
    	virtual std::string dissocier_geniteur() = 0;
    };
     
     
    class Fourmi : public Geniteur_fourmi
    {
    private:
    	Geniteur_fourmi &_parent;
    public:
    	Fourmi(Geniteur_fourmi *adr) : _parent(*adr) {};
    	Fourmi() : _parent(*this) {}
    	std::string dissocier_geniteur() {
    		return (reinterpret_cast<int>(&(this->_parent)) != reinterpret_cast<int>(this)) ? _parent.dissocier_geniteur() : "moi-meme";
    	}
    	int get_parent() {
    		return reinterpret_cast<int>(&(this->_parent));
    	}
    };
     
    class Fourmiliere : public Geniteur_fourmi
    {
    private:
    	std::list<Fourmi *>	_fourmis;
    public:
    	Fourmiliere() : _fourmis() {}
    	Fourmi *naissance()
    	{
    		_fourmis.push_back(new Fourmi(this));
    		return *_fourmis.rbegin();
    	}
    	std::string dissocier_geniteur() { return "une fourmiliere"; }
    };
     
    int main()
    {
    	Fourmiliere fourmil = Fourmiliere();
     
    	Fourmi *fo_solitaire = new Fourmi();
    	Fourmi *fo_fourmil = fourmil.naissance();
     
    	std::cout << "Adresse du parent de fo solitaire : " << fo_solitaire->get_parent() << std::endl;
    	std::cout << "Adresse du parent de fo fourmil : " << fo_fourmil->get_parent() << std::endl;
    	std::cout << "Adresse du fourmil : " << reinterpret_cast<int>(&fourmil) << std::endl;
     
    	std::list<Fourmi *> fourmis;
    	fourmis.push_back(fo_solitaire);
    	fourmis.push_back(fo_fourmil);
    	for (std::list<Fourmi *>::const_iterator ci = fourmis.begin(); ci != fourmis.end(); ++ci)
    	{
    		std::cout << "J ai ete faite par " << (*ci)->dissocier_geniteur() << std::endl;
    	}
    	return 0;
    }

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 19/07/2013, 15h34
  2. Passer d'une classe à une autre
    Par achrafkaran dans le forum Débuter
    Réponses: 1
    Dernier message: 21/04/2013, 14h17
  3. Passer d'une classe à une autre
    Par Sieur_Blabla dans le forum Qt
    Réponses: 16
    Dernier message: 18/08/2010, 11h17
  4. Comment passer request et response à une autre classe
    Par wassimbik dans le forum Développement Web en Java
    Réponses: 0
    Dernier message: 29/07/2010, 16h08
  5. Réponses: 8
    Dernier message: 04/04/2006, 17h29

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