1

I've tried to implement an easy Node Class but when i try to access the child node via the root node its empty, but if i access the child node directly it's filled correctly. Do i have somewhere a logic mistake or can some one give me a hint whats wrong?

Node::Node(QString name, Node *parent)
{
    this->name = name;
    this->parent = parent;

    parent->children.append(this);
}

\\

 class Node
    {
    public:
        Node(QString name) { this->name = name; }
        Node(QString name, Node *parent);
        ~Node(void);

    void addChild(Node *child);

    QString getName() { return name; }
    Node* getChild(int row) { return children[row]; }
    Node* getParent() { return parent; }

    int childCount() { return children.size(); }
    int getRow() {return this->parent->children.indexOf(this);}

    QString log(int tabLevel = -1);

private:
    QString name;
    QList<Node*> children;
    Node *parent;
};

I tried to find the mistake and my result is, that the child node seems to have two different addresses, so there are two different objects but i don't know why :/

    Node rootNode = Node("rootNode");
Node childNode0 = Node("childNode0", &rootNode);
Node childNode1 = Node("childNode1", &rootNode);
Node childNode2 = Node("childNode2", &rootNode);
Node childNode3 = Node("childNode3", &childNode0);
Node childNode4 = Node("childNode4", &childNode0);

qDebug() << "RootNode: " + rootNode.getName() << " | RootChilds: " << rootNode.childCount();
qDebug() << "NodeName: " +rootNode.getChild(0)->getName() << " | NodeChilds: " << rootNode.getChild(0)->childCount();

for(int i = 0; i < childNode0.childCount(); i++)
{
    qDebug() << "NodeName: " << childNode0.getName() << " | NodeChilds: " << childNode0.childCount() << "Child Nr: " << i << " Name -> " << childNode0.getChild(i)->getName();
} 

qDebug() << "Adress via root: " << rootNode.getChild(0) << "\nAdress via node: " << &childNode0 ;

}

That outputs:

"RootNode: rootNode"  | RootChilds:  3 
"NodeName: childNode0"  | NodeChilds:  0 
NodeName:  "childNode0"  | NodeChilds:  2 Child Nr:  0  Name ->  "childNode3" 
NodeName:  "childNode0"  | NodeChilds:  2 Child Nr:  1  Name ->  "childNode4" 
Adress via root:  0x41fc84 
Adress via node:  0x41fcc0 

I hope someone can help me

Regards

Michael Brenndoerfer
  • 3,483
  • 2
  • 39
  • 50
  • Define a copy constructor and an assignment operator for `class Node`. Make them output debug messages. What happens? Now make them private. What happens? – n. m. could be an AI Jan 01 '13 at 04:29

2 Answers2

2

You're giving the parent Node the address to a temporary Node when you do

Node childNode0 = Node("childNode0", &rootNode);
//                ^ rootNode gets this temporary Node as its first child

Rather than constructing Nodes by copying from a temporary, do:

Node childNode0("childNode0", &rootNode);
Fraser
  • 74,704
  • 20
  • 238
  • 215
  • Hi, thank you very much - I trial and error since hours and didn't found the solution. Is it because the copy constructor wasn't implemented as the comment above suggested? – Michael Brenndoerfer Jan 01 '13 at 05:10
  • Another hint that something is amiss is the output line `"NodeName: childNode0" | NodeChilds: 0` - you'd expect the number of children to be `2`, not `0`, after constructing all the objects. See [this answer](http://stackoverflow.com/questions/587070/c-constructor-syntax) for more details. I'm a bit surprised the compiler didn't construct-in-place in this situation though. – tmpearce Jan 01 '13 at 05:11
  • Ah, thanks for the link. I think it's time to refresh my basics :) – Michael Brenndoerfer Jan 01 '13 at 05:15
  • It's because the compiler implemented a copy constructor for you by default that you were able to copy-construct. To avoid this you could declare your copy-constructor `private` and not define it. Or if you're using a C++11 compiler, you could declare the copy-constructor as `deleted`. – Fraser Jan 01 '13 at 05:15
0

I do not think return children[row]; in the function getChild is correct. Are you sure you don't want *children.begin()?

The difference is, that children[row] assumes you have an array of QList<Node*>'s and you want to access the row-th QList, whereas, *children.begin() actually references the first element of the QList.

  • 1
    `QList` [implements](http://doc.qt.digia.com/qt/qlist.html#operator-5b-5d) `T & QList::operator[] ( int i )` making the `[]` get an element from the list, as intended by the questioner. – tmpearce Jan 01 '13 at 04:49
  • As tmperace says. I still tried it. It's exactly the same. Still two different addresses – Michael Brenndoerfer Jan 01 '13 at 04:55
  • Okay, I see... I haven't worked much with the QList class, I was assumed it was similar to the std::list class, which doesn't implement the [] operator. – Jonathan Feucht Jan 01 '13 at 04:55