не понимаю, зачем наследовать knigalist от kniga. Номер там всё равно будет свой собственный, а не номер конкретной книги в списке. Поэтому будет работать неправильно.
Я бы разложил иерархию так:
1. Класс kniga. Он вообще ничего не знает про списки книг. Поскольку я не знаю, какие у книги там ещё должны быть поля и в каком формате (название, автор, ...?), пусть для простоты у неё есть только поле number - номер:
class kniga
{
private:
int number;
public:
int getNumber() const { return number; }
};
- я пока не касаюсь вопроса, как устанавливается этот number. Возможно, в конструкторе, или методом setNumber. Для списка это неважно.
Теперь переходим к списку. Очевидно, что нам нужен хотя бы односвязный список, чтобы мы могли пройти по всем книгам. Однако книга ни про какие другие не знает.
Тут есть две идеи, как это сделать:
1. knigalist - это рекурсивная структура, содержащая "голову"-книгу и "хвост"-список.
2. knigalist лишь управляет связным списком, то есть, содержит его.
Первый подход более "функциональный", что ли. Второй - наверное, более свойственный для языков типа С++, где управление памятью выполняется вручную или почти вручную. Схематически покажу оба:
1. Рекурсивная структура
class knigalist
{
private:
kniga* head_; // первый элемент - по-моему, аналог твоего START
knigalist* tail_; // остальные элементы
public:
knigalist(kniga* head, knigalist* tail) : kniga_(kniga), tail_(tail) {}
// метод add добавляет книгу в указанную позицию, возвращая новый список, с добавленной книгой
knigalist* add(kniga* item, int pos); // реализация такого метода - отдельный любопытный вопрос
// метод getByNumber возвращает книгу, имеющую заданный number
kniga* getByNumber(int number){
if (head_.getNumber() == number){
return head_;
}
else if (tail_ != NULL){
return tail_.getByNumber(number);
}
else return NULL;
}
};
2. управление рекурсивной структурой. Всё, что нам нужно - это прицепить к книге указатель на следующую. Для этого не надо ничего наследовать: обычная композиция является более слабой связью, и её тут достаточно (если интересно, могу отдельно пояснить, что имею в виду под более слабой связью)
class knigalist{
private:
// внутреннее представление для элемента списка. Последний элемент содержит null в качестве next
struct list_item {
kniga* book;
list_item* next;
};
list_item* start_;
int count_; // мало ли, понадобится хранить размер списка
public:
// наш метод получения книги из списка по номеру
kniga* getByNumber(int number)
{
list_item* cur = start_;
for ( ; cur != null; cur = cur->next) {
if (cur->book->getNumber() == number){
// прерываем поиск
break;
}
}
if (cur != null)
return cur->book;
else
return null; // ничего не нашли.
}
};
второй случай более близок к тому, как подобные вещи обычно в C++ реализуются. Скажем, поиск в контейнерах типа std::list реализован похожим образом.
В общем, это всё - информация к размышлению. Я не привожу здесь полных решений
И уж тем более, не настаиваю на каком-то конкретном. Просто задачу можно решить множеством интересных способов. И в каждом случае какие-то из способов будут более удобны или эффективны.