0

I'm trying to make a linked list that keeps track of the number of nodes. I created a static variable numNodes which I increment in the constructor, and which I try to decrement in the deleteNode() function. However, I get the following error:

quest.cpp: In member function 'void List::deleteNode()':
quest.cpp:25: error: 'struct List::node' has no member named 'numNodes'

This works fine with ordinary variables, but I can't seem to access static ones. I read here that I need to declare the variable with something like

int node::numNodes = 0;

but inserting that into the program gave me other errors.

At line 6:

/tmp//ccrjmtbc.o: In function `List::deleteNode()':
quest.cpp:(.text._ZN4List10deleteNodeEv[List::deleteNode()]+0xe): undefined reference to `List::node::numNodes'
quest.cpp:(.text._ZN4List10deleteNodeEv[List::deleteNode()]+0x17): undefined reference to `List::node::numNodes'
collect2: ld returned 1 exit status

At line 29:

quest.cpp:29: error: type 'List::node' is not derived from type 'List'

At line 32:

quest.cpp: At global scope:
quest.cpp:32: error: 'int List::node::numNodes' is not a static member of 'struct List::node'

The problem seems to be that I don't know how to access the static variable when it's encapuslated in another struct. Am I missing something obvious? Is there a better way to do this? Do I need to declare the variable in a header file? (I'm coming to C++ from Java and am unaccustomed to such things.)

Here's the code (stripped of unnecessary clutter):

#include <cstdlib>

struct List {

    struct node {
//     static int numNodes;   //Didn't work
       node() {
            static int numNodes = 0;
            numNodes++;
       }
    };

    node* nodePtr;

    List() {
        nodePtr = NULL;
    }

    void addNode() {
       node* n = new node;
       nodePtr = n;
    }

    void deleteNode() {
        nodePtr->numNodes--;
        delete nodePtr;
    }

//   int node::numNodes = 0;    //Didn't work
};

//int List::node::numNodes = 0;     //Didn't work

int main() {
    List MyList;
    MyList.addNode();
    MyList.deleteNode();
}
Community
  • 1
  • 1
Christabear
  • 33
  • 1
  • 5
  • Shouldn't `numNodes` be a property of the entire list, not of the individual node? – Floris Jun 13 '14 at 17:18
  • Curious- if you're coming from Java, any reason you're using structs and not classes? – Ryan J Jun 13 '14 at 17:19
  • And why are you trying to make numNodes static? It's not like every possible list would have the same number of nodes ... – dragosht Jun 13 '14 at 17:19
  • 1
    My suggestion would be to make `numNodes` a non-static member of `List`, and update it in `List::addNode()/deleteNode()`. `node` itself doesn't need to know about the count. – dlf Jun 13 '14 at 17:20
  • Also, assuming you plan to fix this, but your add/delete functions are not properly coded for a linked list. You're just overwriting the list head pointer with a new node and updating a counter... – Ryan J Jun 13 '14 at 17:22
  • Why do you want make numNodes static? If you have several linked lists they will share numNodes. So if you want to know size of the concrete list you won't be able to do that. Just make numNodes property of the struct List – Ivan Fateev Jun 13 '14 at 17:26
  • @Floris: That sounds like a good alternative. I'm not sure why I didn't think of that, except that I was wondering why this particular method didn't work. I used a static variable earlier to provide each node with an unique ID, and that worked fine until I tried to modify the variable from another method. – Christabear Jun 13 '14 at 17:28
  • @dragosht and JohnPoison: You make a valid point. I wasn't intending to ever make more than one `List`, but I can see how that would lead to problems if I did. – Christabear Jun 13 '14 at 17:30
  • @Ryan J: In the original code, `List` actually is a class and the `addNode()`/`deleteNode()` methods are fully fleshed out. I just modified/deleted that stuff to draw attention to the part of the code that was causing the issue. – Christabear Jun 13 '14 at 17:35
  • @user3736508 Why do you think `numNodes` should be static/global at all? That's simply wrong for such class pattern. – πάντα ῥεῖ Jun 13 '14 at 17:53

1 Answers1

0

Here's what you need to change to make that work:

  1. Uncomment the static int numNodes; line near the top
  2. Remove static int numNodes = 0; in the c'tor.
  3. Uncomment your bottom attempt, int List::node::numNodes = 0;
  4. Ensure that initialization ends up in a cpp file rather than the header.

Then it will work fine. One note, the static numNodes won't serve any practical purpose other than a debugging assistant. If that static is a core part of your design, you're probably on the wrong path.

Sophit
  • 491
  • 2
  • 8
  • Great! This answers the question and achieves the expected result: after creating and deleting a node, `numNodes = 0`. I also think I understand why my code didn't work now. Could you explain what you mean by "won't serve any practical purpose"? It seems like this design is sufficient to, for instance, alert me when the list reaches a certain size. I suppose there may be other better ways of doing this... – Christabear Jun 14 '14 at 00:21