混合抽象类和模板,灾难的秘诀?

时间:2011-03-26 21:46:57

标签: c++ templates inheritance

我遇到以下情况的问题。我有三个参与这个混音的课程。 ListListNodeCity。我有一个List<City *>,其中列表将由一组ListNode<City *>(列表节点周围的标准包装器)组成。

City是一个抽象类,因此有几个从它继承的类可以放在这个列表中并以多态方式访问。 List类有一个getHead()方法,它返回一个指向ListNode的指针。

任何一个城市都有人口,所以为了接触人口,我希望以下方面有效。不是,因此我的问题。我把它分成几块,以便在整个过程中简化:

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

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

getPopulation()返回一个整数。 country定义为List<City*> *city;我将非常感谢您对如何解决我的问题提供任何帮助。

编辑添加更多代码,以便更好地了解我正在使用的内容。首先,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实现中所示。它也调用上面显示的私有插入方法。它看起来像这样: City * somecity = new City(x,y,z); //一些参数整数。 * city_list + = somecity; //其中city_list是一个列表。

2 个答案:

答案 0 :(得分:0)

我认为你有一个变量范围问题。

您的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,该指针将管理对象的生命周期。

答案 1 :(得分:0)

嗯,你能做的是:

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

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

它将采用现有的City(在内存上)并将其放在List节点的头部,依此类推。

如果你想复制它们,也许你可以这样做:

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

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

希望它会对你有所帮助。