Reputation: 9
I have 1 base class, Item
, and 3 derived classes: CD
, Book
, & List
.
I figured out how to print out and add Item
objects, regardless of whether it's a Book
or CD
, in a vector
within a List
object. But I can't figure out how to print only Book
s or only CD
s. I can't make any mentions of a CD
or Book
class in the List
class, and I can't move the bool isBook
or isCD
members to the base class.
class Item
{
protected:
string name;
int id;
public:
//pure virtual methods (ex: virtual bool isID(int);
};
class CD: public Item
{
private:
bool isCD;
public:
//defining virtual methods from base class for class specific operations
virtual string format() { return "Artist: " + name }
};
class Book: public Item
{
private:
bool isBook;
public:
//defining virtual methods from base class for class specific operations
virtual string format() { return "Author: " + name }
};
class List: public Item
{
private:
vector<Item*> holdings;
public:
void Add(Item &adding) {} // already figured out
void printAll() // print all objects in vector regardless of type Book or CD
{
for(auto &i: holdings)
cout << i->format() << '\n';
}
void printBooks(){}
void PrintCDs(){}
}
Upvotes: 0
Views: 49
Reputation: 597051
You don't need the isCD
and isBook
boolean members in each class. You can use dynamic_cast
instead, eg:
class List: public Item
{
private:
vector<Item*> holdings;
public:
...
void printAll() const
{
for(auto *i: holdings)
cout << i->format() << '\n';
}
void printBooks() const
{
for(auto *i: holdings)
{
if (Book *b = dynamic_cast<Book*>(i))
cout << b->format() << '\n';
}
}
void PrintCDs() const
{
for(auto *i: holdings)
{
if (CD *c = dynamic_cast<CD*>(i))
cout << c->format() << '\n';
}
}
};
If you don't want to use this approach, then you can use some additional virtual
methods instead, eg:
class Item
{
...
public:
...
virtual bool isBook() const { return false; }
virtual bool isCD() const { return false; }
};
class CD: public Item
{
...
public:
...
bool isCD() const override { return true; }
};
class Book: public Item
{
...
public:
...
bool isBook() const override { return true; }
};
class List: public Item
{
private:
vector<Item*> holdings;
public:
...
void printAll() const
{
for(auto *i: holdings)
cout << i->format() << '\n';
}
void printBooks() const
{
for(auto *i: holdings)
{
if (i->isBook())
cout << i->format() << '\n';
}
}
void PrintCDs() const
{
for(auto *i: holdings)
{
if (i->isCD())
cout << i->format() << '\n';
}
}
};
Alternatively:
enum ItemType { itCD, itBook };
class Item
{
...
public:
...
virtual ItemType getType() const = 0;
};
class CD: public Item
{
...
public:
...
ItemType getType() const override { return itCD; }
};
class Book: public Item
{
...
public:
...
ItemType getType() const override { return itBook; }
};
class List: public Item
{
private:
vector<Item*> holdings;
public:
...
void printAll() const
{
for(auto *i: holdings)
cout << i->format() << '\n';
}
void printBooks() const
{
for(auto *i: holdings)
{
if (i->getType() == itBook)
cout << i->format() << '\n';
}
}
void PrintCDs() const
{
for(auto *i: holdings)
{
if (i->getType() == itCD)
cout << i->format() << '\n';
}
}
};
Upvotes: 1