Thread: virtual functions and poniters to subclasses

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

    virtual functions and poniters to subclasses

    Hi, i have a base class called Item which contains subclasses, Book, Serial and Newspaper. I have a virtual function called dispInfo which will display the information for that particular type of item. I have another function called GetItem(&Item), which searches through a list of Items for the one with a particular title. This returns a pointer to an Item. My question is how can i use this pointer as a Book, Serial or Newspaper instead of an item. I have something like this, but it always returns an Item.

    [tag]
    Code:
     
    Item* ItemListNode::GetItem(Item &anItem)
    {
    	if(FindItem(anItem)) //increases the iterator until found
    	{		
    		return &*position; //position is a list iterator
    	}
    return NULL;
    }
    [/tag]

    Meanwhile...in main()
    [tag]
    Code:
     
    Book*aBook=NULL;
    
    anItem=ItemDatabase.GetItem(newBook);
    anItem.disInfo();
    [/tag]

    The output is: "I AM AN ITEM!" instead of "I AM A BOOK!"

    Can someone please help!?

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    It sounds like you have a list of Items like this: list<Item>. If that is true, then you need to hold pointers in your list. By holding base class objects, you slice off the derivedness of the objects you add to the list. If you hold base class pointers, then the derivedness is still there and can be accessed through virtual functions.

    This means that you need to use new to create each instance and remember to call delete on each pointer that is erased or cleared from the list (or use a container-compatible smart pointer like boost::shared_ptr).

  3. #3
    Registered User
    Join Date
    Mar 2005
    Posts
    14

    Ok, could u explain i bit more please

    Yes i have list<item> which stores all the items. Could you give me a short example in code which demonstrates what you said because i dont exactly understand what you mean.

  4. #4
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by Asagohan
    Yes i have list<item> which stores all the items. Could you give me a short example in code which demonstrates what you said because i dont exactly understand what you mean.
    I guess you are doing sth like this

    Code:
       list<item> items;
       apple a;
       items.push_back(a);
       banana b;
       items.push_back(b);
    Since the list items holds only item's push_back will only store the item-part of the apple's and bananas. ( this is called slicing ).

    you have to do it this way;

    Code:
       list<item*> items;
       apple * pa= new apple;
       items.push_back(pa);
       banana * pb= new banana;
       items.push_back(pb);
       for ( list<item*>::iterater i = items.begin(); i != items.end(); ++i )
           (*i)->disInfo();

  5. #5
    Registered User
    Join Date
    Mar 2005
    Posts
    14
    ok so what i'm going to do is have an interface which will ask what item they want to insert and they will say Apple for example. And then i say Apple *Apple1=new Apple;

    Then, if i pass this to my function which inserts items into the list, i have to pass it as an item*? And when i retrieve them, i retrieve their pointer, and everything should work? All i have to do is delete Apple1 when i delete it's node right?

  6. #6
    Registered User
    Join Date
    Mar 2005
    Posts
    14
    ok cool its working. Thanx alot.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> All i have to do is delete Apple1 when i delete it's node right?

    Yes. It might be easier to delete the pointer that you stored in the list when you remove it from that list. This will work even if the list holds item*. Just make sure your item class has a virtual destructor, which is required design-wise for all base classes used for polymorphism.

Popular pages Recent additions subscribe to a feed