0

Hey all,

I've been programming an ISBN system of sorts and I'm a little stuck (again).


I want to output my linked list to a text file, so I setup the code like this:

void saveList(char fileName[40])
{
	for ( list< Publication* >::iterator it = pubList.begin(); it != pubList.end(); it++)
	{
		try{
			std::ofstream ouf(fileName);
			if( !ouf ) throw std::ios::failure( "File Error" );

                        ouf<<"Publication,"<<(*it)->getPublisher()<<","<<(*it)->getIsbn();
                        ouf.close();
                }catch( const std::exception& e){
			std::cerr <<e.what()<<endl;
		}
         }
}

Now saving like this works alright with a small issue. I can only access the public functions of the base class object, I can't access the public functions of the derived classes. In addition I can't seem to figure out a way to identify which type of object in the list it is.

in this case I want the oustream to work like this:

if object is of type Publication, output all of publications details to a file.
else if object is of type Book output all of books details to a file.
else if type is ProceedingsBook output those details to a file.

The thing is, how exactly do I identify the object type in the list?

For now I'm writing a specific data member (and get function) identifying each type, I was just wondering if there is another way?

3
Contributors
8
Replies
9
Views
5 Years
Discussion Span
Last Post by termin8tor
0

First you loop solution is very inefficient, with regards to opening and closing files. Just open it once and close it once.

Next a solution to your problem is to have the classes have its own extraction operator. Check this link for more details.

0

I forgot to mention in my first post:

Publication is the base class, with Book being derived from Publication and finally I have a class called ProceedingsBook which is derived from Book.

Publication <- Book <- ProceedingsBook

I have a list setup as follows:

list<publication*> pubList;

I can access all of the Publication objects public functions perfectly fine, the issue arises when I try to access a derived object in the Publication list. As I used pointers I know that the list is correctly populated with the relevant object types, e.g. Books, Publications and Proceedingsbook objects.

The issue is, when I iterate through the list and attempt to access a derived class the code spits out a compile time error.

else if((*it)->getType().compare("Book")==0)
{
    ouf<<(*it)->getType()<<","<<(*it)->getPublisher()<<","<<(*it)->getIsbn()<<","
    <<(*it)->getAuthor()<<","<<(*it)->getTitle()<<endl;
}

Spits out the following compile error:
error C2039: 'getAuthor' : is not a member of 'Publication'
see declaration of 'Publication'

The only reason my code can detect which object it is; is because I have used a virtual function to return the data member "_type".

Any help is really appreciated!

0

Yes I figured from your post that Publication was a base class. If you want to, you can cast the publication to the derived class and take appropriate measure like so:

Book * bk = dynamic_cast(*it);
if(bk != null){
  //publication was a book so do book stuff with 'bk'
}

Edited by firstPerson: n/a

0

First you loop solution is very inefficient, with regards to opening and closing files. Just open it once and close it once.

Next a solution to your problem is to have the classes have its own extraction operator. Check this link for more details.

Thanks a lot for that, readong the article now and it seems very handy, actually I imagine this will come in useful quite often in the future.

0

First you loop solution is very inefficient, with regards to opening and closing files. Just open it once and close it once.

Next a solution to your problem is to have the classes have its own extraction operator. Check this link for more details.

Actually just tried this in practice. When I use oustream like this:

output<<(*it);

having defined my publication class as

friend ostream& operator<<(ostream &out, const Publication &pub);

ostream& operator<<(ostream &out, const Publication &pub)
{
	out << pub._type<<","<< pub._publisher<<","<<pub._isbn<<endl;
	return out;
}

The file output is a 24 digit hexidecimal number (memory address?)

my brain is exploding!

0

make sure you aren't creating 'out' over and over again, therefore overwriting data. And post your new code.

0

I think you should make a method for printing a publication.

class Publication
{
public:
    //Publication doesn't know about what data of subclass should be printed 
    virtual void print(std::ostream& os) const
    {
        os<<isbn<<title;
    }
};

std::ostream& operator<<(std::ostream &os, const Publication &pub)
{
    pub.print(os);
    return out;
}

class Book: public Publication
{
private:
    void print(std::ostream& os) const
    {
        Publication::print(os); //if want isbn and title to be printed.
        //access book data
    }
};

class Magazine: public Publication
{
private:
    void print(std::ostream& os) const
    {
       Publication::print(os); //if want isbn and title to be printed.
       //access magazine data
    }
};

Edited by jinhao: n/a

0

I think you should make a method for printing a publication.

class Publication
{
public:
    //Publication doesn't know about what data of subclass should be printed 
    virtual void print(std::ostream& os) const
    {
        os<<isbn<<title;
    }
};

std::ostream& operator<<(std::ostream &os, const Publication &pub)
{
    pub.print(os);
    return out;
}

class Book: public Publication
{
private:
    void print(std::ostream& os) const
    {
        Publication::print(os); //if want isbn and title to be printed.
        //access book data
    }
};

class Magazine: public Publication
{
private:
    void print(std::ostream& os) const
    {
       Publication::print(os); //if want isbn and title to be printed.
       //access magazine data
    }
};

jinhao, this was exactly what I needed! quite clever aswell. As firstperson suggested, operator overloading was key. I wasn't sure how to apply it to all the derived classes until you showed me. Thankyou to both firstperson and jinhao!

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.