Смешивание абстрактных классов и шаблонов - рецепт катастрофы? - PullRequest
1 голос
/ 27 марта 2011

У меня проблемы со следующей ситуацией. У меня есть три класса, которые участвуют в этом смешении. List, ListNode, City. У меня есть List<City *>, где список будет состоять из набора ListNode<City *> (стандартная оболочка вокруг узлов списка).

City является абстрактным классом, поэтому есть несколько классов, которые наследуют его, которые можно поместить в этот список и получить полиморфный доступ. Класс List имеет метод getHead(), который возвращает указатель на ListNode, который является головой. * * 1010

В любом городе есть население, поэтому, чтобы получить доступ к населению, я ожидал, что сработает следующее. Это не так, таким образом, мой вопрос. Я разбил его на части, чтобы было проще:

    ListNode<City *> *head= country->city_list->getHead();
    City *headnode = *head->getNode();

    cout << "Test: " << headnode->getPopulation() << endl;

getPopulation() возвращает целое число. country определяется как List<City*> *city; Любая помощь в выяснении моей проблемы будет принята с благодарностью.

edit добавление дополнительного кода для лучшего понимания того, с чем я работаю. Во-первых, ListNode:

template <class T>
class ListNode
{
public:
    ListNode() {next = 0;node = 0;};

    ListNode(T *t) {node = t; next = 0;};

    ListNode(const ListNode &l)
    {
        //long copy constructor. snip.
    };

    T *getNode() const { return node; }
    ListNode *getNext() const { return next; };

private:
    T *node;
    ListNode *next;
};

Теперь вот что может иметь значение в классе List.

template <class T>
class List
{
public:
    List()
    {
        head = 0;
        size = 0;
    };

    List(ListNode<T> *t)
    {
        head = t;
        size = 1;
    };

    List(T *t)
    {
        head = new ListNode<T>(t);
        size = 1;
    };

    List(const List<T> &t)
    {
        // long copy constructor. snip.
    };
    //bunch of irrelevent methods.


    ListNode<T> *getHead() const {return head;};

    List &operator+=(T &t)
    {
        this->insert(&t);
        size++;
        return (*this);
    };


private:
    List &insert(T *t)
    {
        ListNode<T> *current = head;
        if (current == 0)
        {
            head = new ListNode<T>(t);
        }
        else
        {
            while (current->getNext() != 0)
            {
                current = current->getNext();
            }
            current->setNext(new ListNode<T>(t));
        }
        return (*this);
    };

    ListNode<T> *head;
    int size;
};

У меня есть догадка, что процесс вставки может быть проблемой. Я вставляю с помощью оператора + = класса List, показанного в реализации List выше. Он также вызывает приватный метод вставки, показанный выше. Это выглядит так: Город * somecity = новый город (x, y, z); // некоторые параметры. целые числа. * city_list + = somecity; // где city_list является списком.

Ответы [ 2 ]

0 голосов
/ 27 марта 2011

Ну, что вы могли бы сделать:

ListNode<City *>* head = new ListNode<City*>(country->city_list->getHead());
City* headnode = head->getNode();

cout << "Test: " << headnode->getPopulation() << endl;

Он возьмет существующий City (в памяти) и поместит его в начало узла списка и т. Д.

и если вы хотите скопировать их, возможно, вы могли бы просто сделать это:

ListNode<City *>* head = new ListNode<City*>*(new City(country->city_list->getHead()));
City* headnode = new City(head->getNode());

cout << "Test: " << headnode->getPopulation() << endl;

Надеюсь, это поможет вам.

0 голосов
/ 27 марта 2011

Я думаю, что у вас проблема с переменной областью видимости.

Ваш класс ListNode содержит указатель на значение узла. Ваш конструктор ListNode получает указатель на значение узла и сохраняет его.

Проблема в том, что указатель на локальную переменную выходит из области видимости. Ваш указатель узла ListNode теперь указывает на объект, который не существует. например в этом примере

addToList(List<int>& myList)
{
    int x = 3;
    myList += x;  // pointer to x is in the list
}
// Out of scope; x no longer exists, but myList has a pointer to it.
// Accessing this node will result in an error.

Существует несколько возможных лекарств:

  1. Ваши ListNode содержат значения, а не указатели. Недостатком здесь является то, что вы будете делать копии значений
  2. Реализация ListNode с использованием умного указателя с подсчетом ссылок, который будет управлять временем жизни объекта.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...