(Во-первых, как заявление об отказе от ответственности, это связано с заданием. Я не прошу никого выполнять мое задание за меня, просто чтобы попытаться помочь мне понять, как правильно реализовать шаблоны.)
Моя текущая настройка:
У меня есть класс А, который является базовым классом.
Класс B, C и D, все дети класса A.
Я пытаюсь создать связанный список, который в пределах одного списка может указывать на B, C или D.
То, что я сейчас настроил, выглядит примерно так:
enum Types { TypeB, TypeC, TypeD }
struct Node
{
void * pointerToElement;
int type;
Node * next;
};
struct Header
{
int counter;
Node * first;
};
Это на самом деле работает. Когда я просматриваю связанный список для распечатки всех элементов, я использую оператор if и int type
, чтобы определить, какой это тип (на основе определенного ENUM), а затем использую static_cast
для приведения указателя void на указатель класса B, C или D.
Теперь мне сказали, что вместо этого я должен использовать шаблоны, что вызывает сильную головную боль. С шаблонами я мало что сделал, но мой опыт работы с ними был не таким уж приятным.
Мое понимание шаблонов состоит в том, что я мог бы использовать его для определения всего связанного списка с ЛЮБЫМ классом B, C или D, но не было бы правдоподобно, чтобы B, C или D появлялись в одном и том же связанном списке?
Я пробовал следующее:
enum Types { TypeB, TypeC, TypeD } // I realise that if templates work, I won't need this
template <class T>
struct Node
{
T * pointerToElement;
int type;
Node<T> * next; // Reason 1 I suspect I could only use one type
};
template <class T>
struct Header
{
int counter;
Node<T> * first; // Reason 2 I suspect I could only use one type
};
Главный вопрос, который у меня есть, должны ли шаблоны это делать? При реализации его в классе мне нужно было указать тип для заголовка, что я не хотел делать, поэтому я также сделал этот класс шаблоном, и он продолжал следовать остальной части моего кода, который не должен Это должен быть шаблон, и, наконец, я попал в main (), где мне нужно было бы определить класс B, C или D.
Комментарии и предложения приветствуются.
Спасибо.
Редактировать
Спасибо всем за комментарии, я, вероятно, узнал больше, пробуя это, чем из лекций.
То, что я сделал, это в значительной степени исключенные шаблоны или, по крайней мере, способ, которым я пытался их использовать. Я использовал шаблоны (к сожалению, ради использования шаблонов), и это работает. Вот что я сейчас сделал (все получилось из всех полезных комментариев ... спасибо!)
template <class T>
struct Node
{
T * pointerToElement;
int type; // I can get rid of this after I go through the code and remove all references to it, which I am doing now.
Node<T> * next; // Reason 1 I suspect I could only use one type
};
template <class T>
struct Header
{
int counter;
Node<T> * first; // Reason 2 I suspect I could only use one type
};
все еще так, как было, но при объявлении Заголовка я объявляю это как:
Заголовок * myHeader;
(я использую структуру классов, идентичную приведенной в приведенном ниже решении).
Итак, это указывает на базовый класс, тот, из которого получены все остальные классы. Затем из-за наследования я могу без проблем хранить там классы B, C или D, и при условии, что все функции, определенные в производных классах (B, C и D), определены в базовом классе, я могу вызвать его непосредственно без приведения (например, все они имеют свою собственную функцию печати, и она вызывает правильную, когда она определена в производном классе).
Я думаю, что идея, которую пытается передать Назначение, является связанным списком, который может использоваться с любым типом, я думаю, что было некоторое недопонимание (вероятно, в основном из-за меня), где я думал, что шаблоны должны были использоваться для определения различных типов классов в каждом узле, скорее они могут использоваться для определения базового класса.