Hey all, I'm attempting to use an STL List to store a list of objects. Now I realise it's quite trivial to store a list of objects of my own definition.

My real question is, how do I fill the list with objects that inherit from a base class.
E.g. I have a class called Book which has the derived class Publication. How would I get the list to accept the base class aswell as derived classes?

currently I am doing it something like this:

list<Book> objectList; //define list
Book temp("Title", "ISBN");
Publication pubTemp("Title", "ISBN", "Publisher");

objectList.push_back(temp);
objectList.push_back(pubTemp);

This code compiles and runs fine, the issue however is that when attempting to create a publication object and store it in the list, it ignores the publisher argument. I realise that this is because the list isn't storing derived classes of Book. Afaik I'm supposed create a list of pointers to the base class of Book.

I have tried this:

list<Book*> bookList;
Publication pubTemp("Title", "ISBN", "Publisher");
objectList.push_back(pubTemp);

However this produces the following error:

error C2664: 'std::list<_Ty>::push_back' : cannot convert parameter 1 from 'Book' to 'Book *const &'

I'm still fairly new with pointers, I understand the theory but the practice is another story. Anyway if anybody could help I'd appreciate it.

You should store the list as the highest type you will need.
If you are going to be calling Publication methods, it should be a list of publications.

You can use a virtual function to print the info for that specific class type.

#include <iostream>
#include <list>

using namespace std;

class Book
{
	public:
	Book(){};
	Book(string t, string i)
	{
		title = t;
		ISBN = i;
	}

	virtual void PrintInfo()
	{
		cout << "Title: " << title << endl << "ISBN: " << ISBN << endl << endl;
	}

	protected:
	string title, ISBN;
};

class Publication: public Book
{
	public:
	Publication(){};
	Publication( string t, string i, string p )
	{
		title = t;
		ISBN = i;
		publisher = p;
	}

	void PrintInfo()
	{
		cout << "Title: " << title << endl << "ISBN: " << ISBN << endl << "Publisher: " << publisher << endl << endl;
	}

	protected:
	string publisher;

};


int main()
{
	list<Book*> books;

	Publication *tmpPublication = new Publication("How to Get Published", "123456789", "McGoodBooks");
	books.push_back(tmpPublication);
	Book *tmpBook = new Book("The Big Book", "987654321");
	books.push_back(tmpBook);

	//print book info
	for( list<Book*>::iterator i = books.begin(); i != books.end(); i++ )
	{
		(*i)->PrintInfo();
	}

	//delete all books from memory
	while( books.size() != 0 )
	{
		delete books.back();
		books.pop_back();
	}


    return 0;
}

Well I have made some reasonable progress with what I want to do, code as follows:

Book.h

#pragma once
#include <string>

class Book
{
public:
	Book(std::string title, int isbn);
	virtual ~Book(void);
	std::string getTitle();
	int getIsbn();
	void setTitle(std::string title);
	void setIsbn(int isbn);
protected:
	std::string _title;
	int _isbn;
};

Publication.h

#pragma once
#include "book.h"

class Publication :
	public Book
{
public:
	Publication(std::string title, int isbn, std::string publisher);
	~Publication(void);
	void setPublisher(std::string publisher);
	std::string getPublisher();
protected:
	std::string _publisher;
};

ListTest.cpp

#include "stdafx.h"
#include "Book.h"
#include "Publication.h"
#include <list>
#include <string>
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
	list<Book*> bookList; //define list

	std::ifstream inf("file.txt");
	string value;
	string book = "Book";
	string publication = "Publication";

	while(!std::getline(inf, value, ',').eof())
	{
		if(!value.compare(book))
		{
			std::string bookTitle;
			std::string isbn;
			std::getline(inf, bookTitle, ',');
			std::getline(inf, isbn);
			Book *temp = new Book(bookTitle,atoi(isbn.c_str()));
			bookList.push_back(temp);
			cout<<"Added: "<<temp->getTitle()<<" ISBN: "<<temp->getIsbn()<<endl<<endl;
		}
		if(!value.compare(publication)){
			std::string bookTitle;
			std::string isbn;
			std::string publisher;

			std::getline(inf, bookTitle, ',');
			std::getline(inf, isbn, ',');
			std::getline(inf, publisher);

			Publication *pubTemp = new Publication(bookTitle,atoi(isbn.c_str()),publisher);

			bookList.push_back(pubTemp);

			cout<<"Added: "<<pubTemp->getTitle()<<" ISBN: "<<pubTemp->getIsbn()<<" Publisher: "<<pubTemp->getPublisher()<<endl<<endl;
		}
	}

	int i = 0;
	for ( list< Book* >::iterator it = bookList.begin(); it != bookList.end(); it++)
	{
		//cout << "The Book: " << (*it)->getTitle() << " ISBN: " << (*it)->getIsbn() <<endl<<endl;
		cout<<"Title: "<<(*it)->getTitle()<<" ISBN: "<<(*it)->getIsbn()<<endl<<" Publisher "<<(*it)->;
	}
}

file.txt

Book,Book of awesome,15643
Publication,Top Gear,56243,Darkhorse
Publication,Pie eaters 12,62345,Black Library
Publication,Grenadiers,32341,Penguin
Book,Charlies Devils,09213
Book,1984,23345

The linked list seems to be working correctly, however I can't access the derived class objects' member fields:

for ( list< Book* >::iterator it = bookList.begin(); it != bookList.end(); it++)
	{
		//cout << "The Book: " << (*it)->getTitle() << " ISBN: " << (*it)->getIsbn() <<endl<<endl;
		cout<<"Title: "<<(*it)->getTitle()<<" ISBN: "<<(*it)->getIsbn()<<endl<<" Publisher "<<(*it)->getPublisher();
	}

When I attempt this I get the following error:

error C2039: 'getPublisher' : is not a member of 'Book'

Now I realise of course that the compiler is correct, but I was under the impression that creating a list of pointers would solve the problem. What am I missing?

Ah sfuo, I see what you mean, that's a pretty simple solution actually! I think I'll give that a shot. It makes sense for me to do it that way. I'm experimenting with it using main at the moment. It's a component of a large application I'm writing hehe.

Anyway thanks for that it's big help!

<Edit> just gave that a try and it didn't quite work, even with the publication the displayContents() function I created would only display the contents as defined in the display function for Book.cpp.

Double Edit, I'm an idiot and forgot to make it virtual haha.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.