0

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.

3
Contributors
4
Replies
5
Views
6 Years
Discussion Span
Last Post by termin8tor
0

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.

0

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;
}
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?

0

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.

Edited by termin8tor: n/a

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.