Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inherited collection of inherited class

I currently have two classes: item and catalog; the latter contains a list of items and some methods for handling them:

class item {
    int index;
    vector<item*> related_items;
    // other member variables and functions
}

class catalog {
    size_t length;
    item* items;
public:
    catalog(size_t l);
    ~catalog();         // delete[] items;
    // other member variables and functions
}

catalog::catalog(size_t l) {
    items = new item[length = l];
    // Set properties of new items
}

(I don't think it would make any difference if items were a vector<item> instead.) Some of the initialization of an item, like populating the list related_items, needs the full set of items, so is done in the catalog constructor.

Now I would like to define new classes: book, which represents a specific type of item, and library, which is a type of catalog that holds books. I would like the library constructor to allocate memory for a certain number of books and then initialize those members of book that are inherited from item in exactly the same way that catalog does. It would then do some further initialization of the remaining members of book.

My initial idea was to make these derived classes, of item and catalog respectively. But as it stands, library can't be a derived class of catalog, because catalog has a pointer to an array of objects of the base class. What is the "best" way of implementing this kind of structure?

like image 719
Stephen Powell Avatar asked Feb 02 '26 19:02

Stephen Powell


1 Answers

If catalog contained an array of pointers instead, say std::vector<std::unique_ptr<item>> it could then hold any subtypes of item. A library inheriting catalog could have member functions only accepting books (which inherit from item) and it could cast the pointers appropriately when returning references to books (or, whatever you want to do with them).

Another alternative is templates:

template<class T>
class catalog {
    std::vector<T> items;
};

class library: public catalog<book> {
    // ...
};

One drawback of templates is that subtypes of different catalog instances don't have a common parent. Whether that is important depends on your design.

Since you don't have any member functions in your example, it's quite hard to tell if inheritance makes any sense at all. library could contain a catalog<book> member, or maybe you can use catalog<book> as it is without a separate library class.

like image 186
eerorika Avatar answered Feb 05 '26 13:02

eerorika