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 :

A possede instance de B et B possede un pointeur sur A


Sujet :

Langage C++

  1. #1
    Membre régulier Avatar de fifafou
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2016
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Seine Maritime (Haute Normandie)

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

    Informations forums :
    Inscription : Janvier 2016
    Messages : 173
    Points : 92
    Points
    92
    Par défaut A possede instance de B et B possede un pointeur sur A
    je veux que A possède une instance de B et que B possède un pointeur sur A
    j'ai essayé la double inclusion:
    Code main.cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include<A.h>
    int main()
    {
        A a;
    }
    Code A.h : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #ifndef A_H
    #define A_H
    #include<B.h>
     
    class B;
    class A
    {
        public:
            A();
        private:
            B m_b;
    };
     
    #endif // A_H
    Code A.cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include "A.h"
     
    A::A()
    {
        B m_b(this);
    }
    Code B.h : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #ifndef B_H
    #define B_H
     
     
    class A;
    class B
    {
        public:
            B(A* a);
        private:
            A* pA;
    };
     
    #endif // B_H
    Code B.cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include "B.h"
     
    B::B(A* a)
    {
        pA=a;
    }
    compilation: A.cpp:3:6: error: no matching function for call to 'B::B()'

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    B n'a pas de constructeur par défaut et tu ne l'initialises pas.
    https://cpp.developpez.com/faq/cpp/?...-l-affectation
    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.

  3. #3
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 562
    Points : 7 628
    Points
    7 628
    Par défaut
    Bonjour,

    dans A::A() tu crées une variable locale qui s’appelle m_b et qui n'a rien à voir avec le membre m_b.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include "A.h"
    #include "B.h"
     
    A::A() : m_b(this)
    {
    }

  4. #4
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 460
    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 460
    Points : 6 064
    Points
    6 064
    Par défaut
    Bonjour,

    Citation Envoyé par fifafou Voir le message
    je veux que A possède une instance de B et que B possède un pointeur sur A
    Attention, ce genre de dépendance circulaire dans laquelle l'objet possédé (B) contient un pointeur vers le possédant (A) est rarement une bonne idée. Il y a des cas où c'est justifié, comme quand on implémente un arbre dont les nœuds possèdent les enfants et connaissent le nœud parent. Mais, dans la majorité des cas, c'est une mauvaise idée.

    Dans ton cas, à quoi correspondent A et B ? Et pourquoi veux-tu que B connaisse A ?

    Attention au piège suivant : pour ton objet A, si le compilateur génère par défaut un constructeur de copie, un constructeur de déplacement, une affectation de copie et une affectation de mouvement, alors toutes ces opérations auront une implémentation incorrecte, car l'objet A de destination contiendra alors un objet B qui pointera vers l'objet A source au lieu de l'objet A de destination.

    Exemple illustratif avec un test du comportement du constructeur de copie incorrect généré par le compilateur :
    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
    #include <cassert>
     
    class A;
     
    class B {
    public:
    	B(A* pa) : m_pa(pa) {}
    	A* m_pa;
    };
     
    class A {
    public:
    	A() : m_b(this) {}
    	B m_b;
    };
     
    int main() {
    	A a1;
    	A a2(a1); // appel au constructeur de copie
    //	assert(a2.m_b.m_pa == &a2); // assertion fausse !
    	assert(a2.m_b.m_pa == &a1); // assertion vraie !
    	return 0;
    }
    Il faut alors redéfinir à la main le constructeur de copie et les autres opérations pour empêcher le compilateur de générer des implémentations incorrectes.

  5. #5
    Membre régulier Avatar de fifafou
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2016
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 22
    Localisation : France, Seine Maritime (Haute Normandie)

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

    Informations forums :
    Inscription : Janvier 2016
    Messages : 173
    Points : 92
    Points
    92
    Par défaut
    En fait c'est pour essayer de debugger un programme ou j'ai ce cas de figure,mais le code corrigé a l'air de marcher sans probleme,alors que dans mon vrai programme j'ai un error:use of incomplete type xxx
    dans le vrai programme il s'agit d'une class World qui possede un instance de Chunkloading(qui contient un thread pour charger les chunks)
    Code World.h : 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
    #ifndef World_H
    #define world_H
    #include <chunkLoading.h>
    #include <chunk.h>
    #include <unordered_map>
    #include <glm/glm.hpp>
    #define GLM_ENABLE_EXPERIMENTAL
    #include "glm/gtx/hash.hpp"
    #include <mutex>
    #include <queue>
    using namespace glm;
    class Chunk;
    class ChunkLoading;
    class World
    {
        public:
            World();
            virtual ~World();
            void addChunks();
            void sendChunk(Chunk* p);
            std::unordered_map<ivec3,Chunk*>::const_iterator getChunk(ivec3 pos);
            std::unordered_map<ivec3,Chunk*>::const_iterator endOfMap(){return chunkMap.end();}
            std::unordered_map<ivec3,Chunk*> chunkMap;
            std::mutex queueMutex;
        private:
            std::queue<Chunk*> chunksLoaded;
            ChunkLoading chunkLoader;
    };
     
    #endif // World_H
    Code chunkloading.h : 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
    #ifndef CHUNKLOADING_H
    #define CHUNKLOADING_H
    #include <world.h>
    #include <queue>
    #include <thread>
    #include <mutex>
    using namespace std;
    class World;
    class ChunkLoading
    {
        public:
            ChunkLoading();
            ChunkLoading(World* world);
            ~ChunkLoading();
            void addChunkToLoad(ivec3 pos){chunksToLoad.push(pos);}
            void loadChunk();
            void loadLoop();
        private:
            queue<ivec3> chunksToLoad;
            World* worldIn;
            thread loadingThread;
    };
     
    #endif // CHUNKLOADING_H

  6. #6
    Expert éminent
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 562
    Points : 7 628
    Points
    7 628
    Par défaut
    Bonjour,

    chunckloading.h inclut world.h et world.h inclut chunckloading.h, on t'a expliqué que ça ne peut pas fonctionner. Ça reste vrai.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 29/04/2018, 01h52
  2. Réponses: 0
    Dernier message: 13/09/2015, 21h47
  3. Récupérer le pointeur sur l'instance
    Par FrançoisLaterite dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 15/05/2014, 16h28
  4. Pointeur sur instance
    Par Fahmi06 dans le forum C++
    Réponses: 9
    Dernier message: 03/08/2007, 10h14
  5. savoir si le client possède flash
    Par goma771 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 19/01/2006, 00h52

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