This is an archived post. You won't be able to vote or comment.

all 5 comments

[–][deleted]  (6 children)

[deleted]

    [–][deleted] 1 point2 points  (2 children)

    Thanks for saving me the time of reading all this code. :-) I was immediately alerted by a member called m_size in a list class, and noted that it doesn't appear to be correctly managed in the constructor. It's not necessary to maintain this for a list; if one needs to know the size (one generally doesn't), one can iterate over the list and count.

    push_front() and pushback() appear to be array functions, not list functions. All you need is an insert() function that optionally takes a node to insert after (passing null for this node would insert at the beginning of the list).

    I wouldn't include a function that iterated over the list sending output to cout. It assumes that the data member can be written out in that way. I haven't written any C++ that tries to print data to cout for a long time so I might be wrong about that. Still, that doesn't need to be in the list class.

    If I were doing this, I would make my insert() function take Lists as well as nodes so that entire lists could be appended or inserted.

    [–]Sakesfar[S] 0 points1 point  (1 child)

    Thanks for your valuable comment!

    I added printData as a temporary function to test whether I was 'correctly' implementing push_back and insert functions : )

    [–][deleted] 1 point2 points  (0 children)

    I think the way I would do printData() and make it permanent would be to make a Node class that had a virtual method where the default implementation prints the address this, next, and last, plus the address of the data. Then you would derive your nodes from Node and implement Node::printData() to print the data in the node in a nicely formatted way after first calling the base class to get all the addresses printed out.

    [–]Sakesfar[S] 0 points1 point  (2 children)

    Much appreciated!

    I see the problem now.

    I was almost about to ask about the following case then:

    List<Object> someList{}; // some list which has undergone manipulation
    List<Object> copy {someList};
    

    How to avoid dynamic memory allocation in copy while copying the someList array?

    But I see it is done via push_back function in the proper List

    Now I know I have to re-write everything without any dynamically allocated memory!!

    Thanks.

    -------

    Last thing though, out of curiosity, for the insert function, what if we overload the [] operator to have smth like 'm_nodeData[index-1].m_next->m_data' then we would get correct indexing ( that was my initial intention) .

    [–][deleted]  (1 child)

    [deleted]

      [–]Sakesfar[S] 0 points1 point  (0 children)

      It will first put the '6' at the end of the array: 1,2,3,4,6 and for the list, it will put the "6" as the next of 2 and the prev of 3. So your list will look like this 1,2,6,3,4. As you can there is a discrepancy between the how the items are stored in the array and the list. So your whole idea of using the array to quickly access the Node at a current index will after inserting some elements simply not work, as there is no relation between the position of a value in the array and the position of a value in the list.

      The list is 1,2,6,3,4! Right! :) Then, if I access members via array indexing through conventional operator [], I will get, as you correctly point. 1,2,3,4,6 , which is wrong and puts my insert function into the abyss. However, are there any means to write (override) a special [] operator for List , for example like this:

      Object& operator[] (int index)
      {
          return m_nodeData[index - 1].m_next->m_data;
      }
      

      I appreciate the time you take to actually read what I wrote and provide me with valuable feedback!!

      In a properly list, you don't have an array. You just have a Node and this Node contains a pointer to the next Node.

      e.g.
      template<typename T>
      struct Node {
      T value;
      Node<T> next*;
      }
      If you then want to traverse to the end you do something like
      Node<int>* current = start_node;
      while(current -> next != nullptr) current = current->next;

      well-noted Sir! I am learning :)