How to find & remove object from a std::list ? - Page 2
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 2 FirstFirst 12
Results 16 to 23 of 23

Thread: How to find & remove object from a std::list ?

  1. #16
    Join Date
    Sep 2003
    Location
    Boston, Ma
    Posts
    52
    I actually tried to take almost the same approach after all the comments to my other post saying that I couldn't derive from std::list but I found myself having to rewrite all the functions that come free with std::list!! So that was the reason that made me go back to the idea of derivation as it would make my instructor happy and would save me a lotta headache.
    Can anybody give me a link to where I can find how the std::list is written so that I might just include all of it inside of my new class without having to derive.
    Thanks.
    Cheers,
    Sofia.

  2. #17
    Join Date
    Sep 2003
    Location
    Boston, Ma
    Posts
    52
    Originally posted by sbrothy
    Ofcourse this would so much simpler if you were allowed to derive from std::list. :-)
    And how would we go about it in case we were!!
    Thanks for taking time to explain all that by the way .
    Sofia.

  3. #18
    Join Date
    Nov 1999
    Location
    Copenhagen, Denmark
    Posts
    265
    If this is an assignment it is conceivable that your instructor hides from you the fact that you shouldn't derive from std::list. The easy way, as you have already discovered, is doing it anyway and mentioning this when turning in your assignment. Never do it in real life! (And if you do it anyway at least inherit privately!)

    Code:
    /*
    	WARNING: This code derives from std::list which is something you should never do in real life because
    			 it has a non-virtual destructor!
    */
    
    #include <list>
    #include <string>
    #include <algorithm>   
    #include <iostream>
    
    using namespace std;
    
    template<class T> 
    class OrderedList: public list<T> {
      public:
    	OrderedList() {}
    	~OrderedList() {}	// <-- Non-virtual destuctor! Same as std::list! This is one reason why you shouldn't derive from std::list
    
    	void pop_first(T t)
    	{
    		OrderedList<T>::iterator itr = find_if(begin(), end(), CompareType(t));
    		if (itr != end())
    			erase(itr);
    	}
    
    private:
    	struct CompareType : public unary_function<T, bool>
    	{
    	    CompareType(const T& t) : m_t(t) {}
    	    bool operator()(const T& t) const { return (m_t == t); }
    
    	private:
    		T m_t;
    	};
    };
    
    
    class Employee
    {
    public:
    	Employee(const string name = "") 
    		: m_name(name)
    	{
    	}
    
    	Employee(const Employee &emp)
    		: m_name(emp.getName()) 
    	{
    	}
    
    	bool operator==(const Employee &emp) const
    	{
    		return (m_name == emp.getName());
    	}
    
    	void setName(const string &name) { m_name = name; }
    	string getName() const { return m_name; }
    
    	friend ostream &operator<<(ostream &os, const Employee &emp)
    	{
    		return os << emp.m_name << endl;
    	}
    
    private:
        string m_name;
    };
    
    
    int main()
    {
    	OrderedList<Employee> employees;
    
    	Employee e("Ford");
    	employees.push_back(e);
    
    	e.setName("Arthur");
    	employees.push_back(e);
    
    	e.setName("Zaphod");
    	employees.push_back(e);
    
    	for(OrderedList<Employee>::const_iterator it = employees.begin(); it != employees.end(); it++)
    		cout << *it;
    
    	// remove first employee named 'Arthur' from the list
    	e.setName("Arthur");
    	employees.pop_first(e);
    
    	for(OrderedList<Employee>::const_iterator it = employees.begin(); it != employees.end(); it++)
    		cout << *it;
    
    	return 0;
    }

    Note that the Employee class has an overloaded == operator for the comparison in CompareType. and a copy constructor for push_back.
    Best regards,
    S. Bro

    "I would be happy to deal with my problems one at the time if they would only line up!"
    -Paul Cilwa, "Borland C++ Insider".

    Other useful fora some of which I ruthlessly clipboarded from other peoples footers.

    MSDN: http://search.microsoft.com/us/dev/default.asp
    WIN 32 Assembler: http://board.win32asmcommunity.net/
    RDBMS: http://www.dbforums.com
    Robert's Perl Tutorial: http://www.sthomas.net/roberts-perl-tutorial.htm
    Merriam-Webster Online: http://www.m-w.com/home.htm
    Writing Unmaintainable Code: http://mindprod.com/unmain.html

  4. #19
    Join Date
    Apr 1999
    Posts
    27,427
    Originally posted by megabyte
    I actually tried to take almost the same approach after all the comments to my other post saying that I couldn't derive from std::list but I found myself having to rewrite all the functions that come free with std::list!!
    Why are you trying to implement all the functions?

    a) You implement the functions that you need to perform in terms of the std::list member.

    b) You now have a chance to give your new functions names that can be understood by others using your class. For example, instead of erase(), you can now call your function EraseElementFromList() and you call your std::list erase function internally.

    c) Who says that the class will always use a list? What if in the future, your class internals now want to use a std::map, a std::vector, or a std::deque instead of a std::list? You now have to force the user of the class to change their code, all because you've changed your base class from, say std::list to a std::map. If you did steps a) and b), the users of your new class will not have to change any code, since the underlying structure used is hidden from them.
    Can anybody give me a link to where I can find how the std::list is written so that I might just include all of it inside of my new class without having to derive.
    See steps a) and b). You create member functions that fit your needs for your class. If std::list::splice() is not necessary for your class, you don't need to include it. Your object has to make sense, and if splicing an ordered list (I believe this is what you wanted to do) doesn't make sense, why provide a member function for it?

    Regards,

    Paul McKenzie

  5. #20
    Join Date
    Sep 2003
    Location
    Boston, Ma
    Posts
    52
    Thanks a million for that nice explaination sbrothy.
    I have a bit of a problem still though and I will really appreciate any help as this has been driving me nuts.
    I have another function that is almost the same as the void pop_first(T t) above. The only difference is that this one erases the member and pushes it to the back of my list. Something like:
    Code:
    void pop_first_push_back(T t)
    {
    typename	OrderedList<T>::iterator itr = find_if(begin(), end(), CompareType(t));
    typename	OrderedList<T>::iterator itr;
    if (itr != end())
    {	
      itrr=itr
      erase(itr);
      //push itrr to the back of my list
    }
    I don't know how to push back the member I'm erasing as I haven't declared any lists inside the scope(hence I can't do something like MyList.push_back(itrr); )
    Thanks for any help.
    Cheers,
    Sofia.

  6. #21
    Join Date
    Apr 1999
    Posts
    27,427
    Originally posted by megabyte
    I don't know how to push back the member I'm erasing as I haven't declared any lists inside the scope(hence I can't do something like MyList.push_back(itrr);
    You have a list<T>, therefore your list holds T, not iterators. You should be placing a T in the list.
    Code:
    void pop_first_push_back(T t)
    {
        typename  OrderedList<T>::iterator itr = find_if(begin(), end(), CompareType(t));
        T temp;
        if (itr != end())
       {	
           temp = *itr;
           erase(itr);
           push_back( temp );
        }
    }
    Regards,

    Paul McKenzie

  7. #22
    Join Date
    Apr 1999
    Posts
    27,427
    Originally posted by sbrothy
    Note that the Employee class has an overloaded == operator for the comparison in CompareType. and a copy constructor for push_back.
    The Employee class does not need a user-defined copy constructor. The only member, a std::string is copyable, therefore there is no need for a user-defined copy constructor.

    Also, if you are to provide a copy constructor, an assignment operator (which is also not necessary) should be provided, along with a destructor (the "rule of three" in C++).

    Regards,

    Paul McKenzie

  8. #23
    Join Date
    Sep 2003
    Location
    Boston, Ma
    Posts
    52
    Thank you very much for the explanation Paul.
    Regards,
    Sofia.

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center