2015-04-16 199 views
3

我目前有两类:itemcatalog;后者包含的item秒的列表,并处理它们的一些方法:继承的继承集合

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 
} 

(我不认为这将使任何区别,如果items是一个vector<item>代替。)一些的item的初始化,像填充列表related_items,需要全套item s,因此在catalog构造函数中完成。现在

我想定义新类:book,它代表了特定类型的itemlibrary,这是保存book个类型的catalog。我希望library构造函数为一定数量的book s分配内存,然后用与catalog完全相同的方式初始化那些从item继承的book成员。然后它会对book的其余成员进行一些进一步的初始化。

我最初的想法是使这些派生类分别为itemcatalog。但是,因为library不能是catalog的派生类,因为catalog有一个指向基类对象数组的指针。实施这种结构的“最佳”方式是什么?

+3

模板和[模板专业化](http://www.cprogramming.com/tutorial/template_specialization.html)也许? –

+1

图书馆从目录中检索有什么问题?它也会指向一系列物品,但就你而言,所有这些物品都将成为书籍。 –

+0

@Othman然后你会有[对象切片](http://en.wikipedia.org/wiki/Object_slicing),因为'items'是一个'item' *对象*的数组。 –

回答

2

如果catalog包含一个指针数组而不是std::vector<std::unique_ptr<item>>那么它可以包含item的任何子类型。 A library继承catalog可能会有成员函数只接受book s(从item继承),并且它可以在返回对图书的引用(或任何您想要对它们执行的操作)时适当地转换指针。

另一种方法是模板:模板

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

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

一个缺点是不同catalog实例的亚型没有一个共同的父。这是否重要取决于您的设计。

由于您的示例中没有任何成员函数,因此很难判断继承是否有意义。 library可能包含catalog<book>成员,或者您可以使用catalog<book>,因为它没有单独的library类。

+0

感谢您的建议。我想避免将'dynamic_cast''item *'变成'book *',但我承认这主要是出于美学原因。我想我最终会沿着模板路径走得更远,并使用'template class item'和'template class catalog'。当(如果)我清理细节时,我会作为答案发布。 –

+0

'static_cast'就足够了*如果*'library'确保只有'book'存在于vector中。 – user2079303