Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Probleme de membre static dans une classe de noeud

3 réponses
Avatar
DELORME Frederic
j'ai une classe CNode qui est articulée autour d'une membre statique (enfin,
c'est ce que j'aimerai ...)

La déclaration est la suivante :

<code> -----------------------------------------------------------
#include <iostream>
#include <cstring>

#ifndef E3DCNODE_H
#define E3DCNODE_H

using namespace std;

namespace E3D {

/**
Noeud d'un arbre

@author DELORME Frederic
*/
class CNode{
public:
        CNode();
        CNode(string psNodeName);
        CNode(string psNodeName, CNode *poParentNode);

        ~CNode();
        void init();
        void addChild(CNode *poNodeChild);
        void attachTo(CNode *poNodeParent);
        void remove(CNode *poNodeChild);

protected:
        static CNode *m_BaseNode;
        // Nom du noeud
        string m_Name;
        // Noeud Racine
        // Parent de ce noeud
        CNode *m_Parent;
        // Premier Enfant de ce noeud
        CNode *m_Child;
        // Enfant suivant de ce noeud
        CNode *m_Next;
        // Enfant précédent de ce noeud
        CNode *m_Prev;
};

};
#endif
----------------------------------------------------------- <code>

L'implémentation est la suivante :

<code> -----------------------------------------------------------
#include "cnode.h"

namespace E3D {

CNode::CNode(){
        this->m_Name = "noname";
        this->init();
}
/*!
        Création d'un noeud attaché à un parent.
        \fn E3D::CNode::CNode(string *psNodeName)
        \param psNodeName : Nom du noeud à créer.
 */
CNode::CNode(string psNodeName)
{
        this->m_Name = psNodeName;
        this->init();
}
/*!
        Création d'un noeud attaché à un parent.
        \fn E3D::CNode::CNode(CNode *poParentNode)
        \param poNodeName : Nom du noeud à créer.
        \param poParentNode : Noeud parent.
 */
CNode::CNode(string psNodeName, CNode *poParentNode)
{
        this->m_Name = psNodeName;
        poParentNode->addChild(this);
}
/*!
        Constructeur par défaut
        \fn E3D::CNode::CNode().
*/
CNode::~CNode()
{
        if(this->m_Child) delete this->m_Child;
        if(this->m_Next) delete this->m_Next;
        if(this->m_Prev) delete this->m_Prev;
}

void CNode::init(){
        if(!this->m_BaseNode){
                // oui, alors, on l'initialise
                this->m_BaseNode = this;
                this->m_Parent = NULL;
        }else{
                // Sinon on l'ajoute en tant qu'enfant.
                this->m_BaseNode->addChild(this);
        }
}

/*!
        Ajout d'un enfant à cet objet.
        \fn E3D::CNode::addChild(const CNode *poNodeChild).
        \param poNodeChild : Noeud enfant à ajouter.
*/
void CNode::addChild(CNode *poNodeChild){

        poNodeChild->attachTo(this);
/*      // Ce noeud a-t-il des enfants ?
        if( this->m_Child == NULL ){
                // NON, alors on l'ajoute en tant que premier enfant
                this->m_Child = poNodeChild;
                poNodeChild->m_Parent = this;
        }else{
                // OUI, alors, on recherche le dernier enfant
                CNode *ptrNode = this->m_Child;
                while( ptrNode->m_Next != NULL ){
                        ptrNode = ptrNode->m_Next;
                }
                ptrNode->m_Next = poNodeChild;
                poNodeChild->m_Prev = ptrNode;
        }
*/
}
/*!
        Attacher le Noeud courant au noeud parent donné.
        \fn E3D::CNode::attachTo(CNode *poNodeParent)
        \param poNodeParent : Parent auquel attacher le noeud.
*/
void CNode::attachTo(CNode *poNodeParent){
        if( poNodeParent->m_Child == NULL ){
                poNodeParent->m_Child = this;
        }else{
                CNode *ptrNode = poNodeParent->m_Child;
                while( ptrNode->m_Next != NULL ){
                        ptrNode = ptrNode->m_Next;
                }
                ptrNode->m_Next = this;
        }
}

/*!
        Supprimer le noeud donné.
        \fn E3D::CNode::remove(CNode *poNode).
        \param poNode : Noeud à supprimer
*/
void CNode::remove(CNode *poNode){
        // on récupère les précédents et suivants
        if(poNode){
                CNode *ptrNext = poNode->m_Next;
                CNode *ptrPrev = poNode->m_Prev;
                if( &poNode != &this->m_BaseNode ){

                // On enlève le noeud de la chaine
                if(ptrPrev!=NULL && ptrPrev->m_Next!=NULL) ptrPrev->m_Next = ptrNext;
                if(ptrNext!=NULL && ptrNext->m_Prev!=NULL) ptrNext->m_Prev = ptrPrev;
                delete poNode;
                }else{
                        delete this;
                }
        }
}

};
----------------------------------------------------------- <code>


et j'ai l'erreur suivante à la compilation ....


<log> ------------------------------------------------------------
*/home/fred/Projets/cpp/testsdl/src/cnode.cpp:61: undefined reference to
`E3D::CNode::m_BaseNode'
*cnode.o(.text+0x50b):/home/fred/Projets/cpp/testsdl/src/cnode.cpp:63:
undefined reference to `E3D::CNode::m_BaseNode'
*cnode.o(.text+0x523):/home/fred/Projets/cpp/testsdl/src/cnode.cpp:67:
undefined reference to `E3D::CNode::m_BaseNode'
*/home/fred/Projets/cpp/testsdl/src/cnode.cpp:122: undefined reference to
`E3D::CNode::m_BaseNode'
------------------------------------------------------------ <log>

Vous avez une idée du pourquoi du comment ?

Par avance merci !

F.Delorme.

3 réponses

Avatar
Loïc Joly
DELORME Frederic wrote:


Vous avez une idée du pourquoi du comment ?


Non, parce que ton code ne donne pas particulièrement envie d'être lu,
il y en a trop. Serait-il possible de poster ce que les gens de fctt
appellent un ECM, c'est à dire un exemple complet et minimal. Le strict
minimum compilable qui reproduise le problème. Deux avantages :

- Les gens qui lisent en ont une vue synthètique et sont plus à même de
faire l'effort de chercher l'erreur ;
- Souvent en faisant ça, on se rend compte soi même du problème.

Enfin, si tu pouvait indiquer la ligne référencée dans le message
d'erreur, ça nous éviterait de devoir recompter à la main.

Merci,

--
Loïc

Avatar
Olivier.luong
A vu de nez, ton membre static n'est pas initialisé,
il te faudrait quelque chose comme :

CNode::m_BaseNode= NULL;

dans ton .CPP
Olivier

"DELORME Frederic" a écrit dans le message de
news: 41571a6e$0$25680$
j'ai une classe CNode qui est articulée autour d'une membre statique
(enfin,
c'est ce que j'aimerai ...)

La déclaration est la suivante :

<code> -----------------------------------------------------------
#include <iostream>
#include <cstring>

#ifndef E3DCNODE_H
#define E3DCNODE_H

using namespace std;

namespace E3D {

/**
Noeud d'un arbre

@author DELORME Frederic
*/
class CNode{
public:
CNode();
CNode(string psNodeName);
CNode(string psNodeName, CNode *poParentNode);

~CNode();
void init();
void addChild(CNode *poNodeChild);
void attachTo(CNode *poNodeParent);
void remove(CNode *poNodeChild);

protected:
static CNode *m_BaseNode;
// Nom du noeud
string m_Name;
// Noeud Racine
// Parent de ce noeud
CNode *m_Parent;
// Premier Enfant de ce noeud
CNode *m_Child;
// Enfant suivant de ce noeud
CNode *m_Next;
// Enfant précédent de ce noeud
CNode *m_Prev;
};

};
#endif
----------------------------------------------------------- <code>

L'implémentation est la suivante :

<code> -----------------------------------------------------------
#include "cnode.h"

namespace E3D {

CNode::CNode(){
this->m_Name = "noname";
this->init();
}
/*!
Création d'un noeud attaché à un parent.
fn E3D::CNode::CNode(string *psNodeName)
param psNodeName : Nom du noeud à créer.
*/
CNode::CNode(string psNodeName)
{
this->m_Name = psNodeName;
this->init();
}
/*!
Création d'un noeud attaché à un parent.
fn E3D::CNode::CNode(CNode *poParentNode)
param poNodeName : Nom du noeud à créer.
param poParentNode : Noeud parent.
*/
CNode::CNode(string psNodeName, CNode *poParentNode)
{
this->m_Name = psNodeName;
poParentNode->addChild(this);
}
/*!
Constructeur par défaut
fn E3D::CNode::CNode().
*/
CNode::~CNode()
{
if(this->m_Child) delete this->m_Child;
if(this->m_Next) delete this->m_Next;
if(this->m_Prev) delete this->m_Prev;
}

void CNode::init(){
if(!this->m_BaseNode){
// oui, alors, on l'initialise
this->m_BaseNode = this;
this->m_Parent = NULL;
}else{
// Sinon on l'ajoute en tant qu'enfant.
this->m_BaseNode->addChild(this);
}
}

/*!
Ajout d'un enfant à cet objet.
fn E3D::CNode::addChild(const CNode *poNodeChild).
param poNodeChild : Noeud enfant à ajouter.
*/
void CNode::addChild(CNode *poNodeChild){

poNodeChild->attachTo(this);
/* // Ce noeud a-t-il des enfants ?
if( this->m_Child == NULL ){
// NON, alors on l'ajoute en tant que premier enfant
this->m_Child = poNodeChild;
poNodeChild->m_Parent = this;
}else{
// OUI, alors, on recherche le dernier enfant
CNode *ptrNode = this->m_Child;
while( ptrNode->m_Next != NULL ){
ptrNode = ptrNode->m_Next;
}
ptrNode->m_Next = poNodeChild;
poNodeChild->m_Prev = ptrNode;
}
*/
}
/*!
Attacher le Noeud courant au noeud parent donné.
fn E3D::CNode::attachTo(CNode *poNodeParent)
param poNodeParent : Parent auquel attacher le noeud.
*/
void CNode::attachTo(CNode *poNodeParent){
if( poNodeParent->m_Child == NULL ){
poNodeParent->m_Child = this;
}else{
CNode *ptrNode = poNodeParent->m_Child;
while( ptrNode->m_Next != NULL ){
ptrNode = ptrNode->m_Next;
}
ptrNode->m_Next = this;
}
}

/*!
Supprimer le noeud donné.
fn E3D::CNode::remove(CNode *poNode).
param poNode : Noeud à supprimer
*/
void CNode::remove(CNode *poNode){
// on récupère les précédents et suivants
if(poNode){
CNode *ptrNext = poNode->m_Next;
CNode *ptrPrev = poNode->m_Prev;
if( &poNode != &this->m_BaseNode ){

// On enlève le noeud de la chaine
if(ptrPrev!=NULL && ptrPrev->m_Next!=NULL) ptrPrev->m_Next = ptrNext;
if(ptrNext!=NULL && ptrNext->m_Prev!=NULL) ptrNext->m_Prev = ptrPrev;
delete poNode;
}else{
delete this;
}
}
}

};
----------------------------------------------------------- <code>


et j'ai l'erreur suivante à la compilation ....


<log> ------------------------------------------------------------
*/home/fred/Projets/cpp/testsdl/src/cnode.cpp:61: undefined reference to
`E3D::CNode::m_BaseNode'
*cnode.o(.text+0x50b):/home/fred/Projets/cpp/testsdl/src/cnode.cpp:63:
undefined reference to `E3D::CNode::m_BaseNode'
*cnode.o(.text+0x523):/home/fred/Projets/cpp/testsdl/src/cnode.cpp:67:
undefined reference to `E3D::CNode::m_BaseNode'
*/home/fred/Projets/cpp/testsdl/src/cnode.cpp:122: undefined reference to
`E3D::CNode::m_BaseNode'
------------------------------------------------------------ <log>

Vous avez une idée du pourquoi du comment ?

Par avance merci !

F.Delorme.


Avatar
DELORME Frederic
Loïc Joly wrote:

DELORME Frederic wrote:


Vous avez une idée du pourquoi du comment ?


Non, parce que ton code ne donne pas particulièrement envie d'être lu,
il y en a trop. Serait-il possible de poster ce que les gens de fctt
appellent un ECM, c'est à dire un exemple complet et minimal. Le strict
minimum compilable qui reproduise le problème. Deux avantages :

- Les gens qui lisent en ont une vue synthètique et sont plus à même de
faire l'effort de chercher l'erreur ;
- Souvent en faisant ça, on se rend compte soi même du problème.

Enfin, si tu pouvait indiquer la ligne référencée dans le message
d'erreur, ça nous éviterait de devoir recompter à la main.

Merci,

Désolé, je serai plus conci la prochaine fois.

Merci Olivier, c'était bien cela l'erreur.
De plus, Dave Eberly m'a fait une super réponse sur un autre forums (ou
d'ailleurs j'avais posté par erreur.... la fatigue oulalala ...)
Merci a tous.

--
Fred