Thread: Stl lists and user defined types

  1. #1
    Registered User
    Join Date
    Mar 2005
    Posts
    8

    Stl lists and user defined types

    If been trying to use the STL list with my own class, to make up nodes.
    In other words, what I am trying to do is that instead of just pushing in just an integer or a character for example, I want to be able to push in my own object, for example a coordinate with two int variables in it. Here is the code:

    This is the node:
    Code:
    #ifndef COORDINATE_H
    #define COORDINATE_H
    
    
    class Coordinate
    {
    public:
        int yvalue;
        int zvalue;
        Coordinate( int, int );
    };
    
    
    Coordinate::Coordinate( int value1, int value2 )
    {
        yvalue = value1;
        zvalue = value2;
    
        
    }
    
    #endif
    And now my main:
    Code:
    #include <iostream>
    #include <list>
    
    #include "coordinate.h"
    
    using namespace std;
    
    int main()
    {
        list< Coordinate > myGrid;
        list< Coordinate >::iterator iter;
    
        Coordinate *newPtr1 = new Coordinate( 0, 1 );
        Coordinate *newPtr2 = new Coordinate( 0, 2 );
        Coordinate *newPtr3 = new Coordinate( 1, 1 );
    
        myGrid.push_back( newPtr1 );
        myGrid.push_back( newPtr2 );
        myGrid.push_back( newPtr3 );
    
        iter =  myGrid.begin();
       
    }
    My question is: how do I reference each individual member of the coordinate. Can I do just [cout << *iter->yvalue;] ?
    Or, do I need to create the necesary functions inside the coordinate class to return the desired data?

    So far every example and tutorial that I have seen deals only with lists and simple data types like ints and strings. But none that I have seen with user defined types. If I could use the stl list it would facilitate so much for me.

    Please help?

    Thanks,
    Figa

  2. #2
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>myGrid.push_back( newPtr1 );
    Just like to point out, your std::list contains Coordinate objects, not pointers. So you'll need to either make it a std::list<Coordinate*> or else push actual objects onto the list.

    >>Can I do just [cout << *iter->yvalue;] ?
    Yes, if it's a list<Coordinate*>. Otherwise it would either be (*iter).yvalue or iter->yvalue. Normally it will work OK without putting the () around *iter, but there are some rare-ish cases in which order-of-operation will cause you problems without them.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  3. #3
    Registered User
    Join Date
    Mar 2005
    Posts
    8
    Hey thanks for your quick reply, it helped a lot. Some times it takes a second person to point out the obvious, like the fact that I was not pushing actual objects. Dope!!

    Thanks again, and here is how I fixed the code in case someone reads this thread with the same questions in mind.

    Code:
    #include <iostream>
    #include <list>
    
    #include "coordinate.h"
    
    using namespace std;
    
    int main()
    {
        list< Coordinate > myGrid;
        list< Coordinate >::iterator iter;
    
        Coordinate *newPtr1 = new Coordinate( 0, 1 );
        Coordinate *newPtr2 = new Coordinate( 0, 2 );
        Coordinate *newPtr3 = new Coordinate( 1, 1 );
    
        myGrid.push_back( *newPtr1 );
        myGrid.push_back( *newPtr2 );
        myGrid.push_back( *newPtr3 );
    
        iter =  myGrid.begin();
        cout << "\n\nThe Coordinate's value is: (" << iter->yvalue << ", " << iter->zvalue
             << ")" << endl;
    
        iter++;
        cout << "\n\nThe next Coordinate's value is: (" << iter->yvalue << ", " << iter->zvalue
             << ")" << endl;
    
        iter++;
        cout << "\n\nThe last Coordinate's value is: (" << iter->yvalue << ", " << iter->zvalue
             << ")\n\n";
        
    }

    Figa

  4. #4
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Easier to just do this:
    Code:
    list< Coordinate > myGrid;
    
    myGrid.push_back( Coordinate( 0, 1 ) );
    myGrid.push_back( Coordinate( 0, 2 ) );
    myGrid.push_back( Coordinate( 1, 1 ) );
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  5. #5
    Registered User
    Join Date
    Mar 2005
    Posts
    8
    Quote Originally Posted by hk_mp5kpdw
    Easier to just do this:
    Code:
    list< Coordinate > myGrid;
    
    myGrid.push_back( Coordinate( 0, 1 ) );
    myGrid.push_back( Coordinate( 0, 2 ) );
    myGrid.push_back( Coordinate( 1, 1 ) );
    So I guess that dynamically creates the new nodes, right? Cool. that is eaven easier.

    Thanks.

  6. #6
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Well, no. Your code, using new, creates the nodes dynamically, meaning that you'll have to manually call delete on each pointer after removing them from the list. hk_mp5kpdw's version simply creates an object by calling the constructor, and then directly passes it to push_back() - that's called an unnamed variable, I believe, and it goes out of scope immediately after push_back() completes, but the copy in the list will remain.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  7. #7
    Registered User
    Join Date
    Mar 2005
    Posts
    8
    Few more questions:
    First:
    Quote Originally Posted by Hunter2
    Well, no. Your code, using new, creates the nodes dynamically, meaning that you'll have to manually call delete on each pointer after removing them from the list. hk_mp5kpdw's version simply creates an object by calling the constructor, and then directly passes it to push_back() - that's called an unnamed variable, I believe, and it goes out of scope immediately after push_back() completes, but the copy in the list will remain.
    So does that means that the destructor would then take care of deleting the object and freeing up the memory once the object is removed from the list?

    Second:
    Code:
    #include <iostream>
    #include <list>
    #include "coordinate.h"
    
    using namespace std;
    
    void print(const list< Coordinate > &listRef);
    
    int main()
    {
        list< Coordinate > myGrid;    
        myGrid.push_back( Coordinate( 0, 1 ) );
        myGrid.push_back( Coordinate( 0, 2 ) );
        myGrid.push_back( Coordinate( 1, 1 ) );
    
        print(myGrid);
    
        return 0;
    }
    
        
    void print( const list< Coordinate > &listRef )
    {
           if( listRef.empty() )
            cout << "\nlist is empty\n";
    
           else
           {
               cout << "\nHere is the Print Out\n";
    
               list< Coordinate >::iterator iter;
    
               //iter = listRef.begin();       //gives me an error when compiling
    
               cout << "\n\nThe Coordinate's value is: (" << iter->yvalue << ", " << iter->zvalue
                    << ")" << endl;
    
               iter++;
               cout << "\n\nThe next Coordinate's value is: (" << iter->yvalue << ", " << iter->zvalue
                    << ")" << endl;
    
    
               iter++;
               cout << "\n\nThe last Coordinate's value is: (" << iter->yvalue << ", " << iter->zvalue
                    << ")\n\n";
    
    
            }    
            
    }
    What is the right way to pass the
    Code:
     
    const list< Coordinate > &listRef
    argument? if that is what I am doing wrong here.

    'Cause if I try to do a
    Code:
     iter = listRef.begin();
    then the compoiler gives me an error. What is the right way to do this?

    Thanks once again,
    Figa
    Last edited by figa; 03-28-2005 at 12:02 PM.

  8. #8
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    The problem is that you're passing a const reference, and then trying to get a non-const iterator to listRef, which would mean that you could modify listRef even though it's const. Clearly, there would be something wrong in that scenario. If you're just trying to print the values (i.e. not erase them or whatever), you can use a list<Coordinate>::const_iterator instead, which will work fine with a const reference.

    **EDIT**
    So does that means that the destructor would then take care of deleting the object and freeing up the memory once the object is removed from the list?
    Assuming you're referring to the method(s) that doesn't use new, yes push_back() on all of the STL containers will create a copy of the object internally, and the container will be responsible for cleanup of the object after it is erased. If you didn't create the object dynamically to pass to the container, then the original object will go out of scope eventually and be destructed, leaving only the copy in the container which will be cleaned up automatically.

    However, if you dynamically allocate an object and the pass (*the_pointer) to push_back(), the container will create an internal copy of the object and will erase the copy of the object, but you will still be responsible for deleting the dynamic memory, since dynamic memory does not go out of scope.
    Last edited by Hunter2; 03-28-2005 at 12:09 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  9. #9
    Registered User
    Join Date
    Mar 2005
    Posts
    8
    Great!! That worked. I kind of feel stupid. I should have seen it.

    Code:
               list< Coordinate >::const_iterator iter;
    
               iter = listRef.begin();
    Thank you.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  2. Totally confused on assigment using linked lists
    By Uchihanokonoha in forum C++ Programming
    Replies: 8
    Last Post: 01-05-2008, 04:49 PM
  3. Lists: adding fields (not nodes) & more
    By Mariano L Gappa in forum C++ Programming
    Replies: 15
    Last Post: 11-09-2005, 07:26 PM
  4. Linked Lists 101
    By The Brain in forum C++ Programming
    Replies: 5
    Last Post: 07-24-2004, 04:32 PM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM