Использование шаблонов C ++ в связанных списках с несколькими различными типами, появляющимися в списке - PullRequest
2 голосов
/ 25 мая 2011

(Во-первых, как заявление об отказе от ответственности, это связано с заданием. Я не прошу никого выполнять мое задание за меня, просто чтобы попытаться помочь мне понять, как правильно реализовать шаблоны.)

Моя текущая настройка:

У меня есть класс А, который является базовым классом. Класс 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), определены в базовом классе, я могу вызвать его непосредственно без приведения (например, все они имеют свою собственную функцию печати, и она вызывает правильную, когда она определена в производном классе).

Я думаю, что идея, которую пытается передать Назначение, является связанным списком, который может использоваться с любым типом, я думаю, что было некоторое недопонимание (вероятно, в основном из-за меня), где я думал, что шаблоны должны были использоваться для определения различных типов классов в каждом узле, скорее они могут использоваться для определения базового класса.

1 Ответ

1 голос
/ 25 мая 2011

Вместо шаблонов вы должны использовать наследование.Шаблоны, как вы уже догадались, создают экземпляр для каждого типа T, а это не то, что вам нужно.

Ваш код должен выглядеть примерно так:

class A{...};
class B: public A{...};
class C: public A{...};
class D: public A{...};
struct Node{
    A *next;
}

, который вы можете назначитьnext указывает на A, B, C или D.Обязательно пометьте функции-члены как virtual, где это необходимо.

...