混合抽象类和模板会导致灾难吗?

发布于 2024-10-27 02:18:14 字数 2463 浏览 0 评论 0原文

我遇到以下情况的问题。我有三个类参与了这种混合。 列表ListNode城市。我有一个 List,其中列表将由一组 ListNode (列表节点周围的标准包装器)组成。

City 是一个抽象类,因此有几个继承自它的类可以放入此列表中并进行多态访问。 List 类有一个 getHead() 方法,该方法返回一个指向作为头的 ListNode 的指针。

任何城市都有人口,因此要访问人口,我希望以下方法能够发挥作用。事实并非如此,因此我的问题是。我将其分解为几个部分,以使其更简单:

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

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

getPopulation() 返回一个整数。 country 定义为 List; *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 实现所示。它还调用上面所示的私有插入方法。它看起来像这样: 城市 *somecity = 新城市(x,y,z); //一些参数。整数。 *city_list += 某个城市; // 其中 city_list 是一个列表。

I'm having problems with the following situation. I have three classes that are involved in this mixup. List, ListNode, City. I have a List<City *>, where the list will be made up of a set of ListNode<City *> (standard wrapper around the list nodes).

City is an abstract class, so there are several classes that inherit from it that could be placed in this list and accessed polymorphically. The List class has a getHead() method which returns a pointer to a ListNode that is the head.

Any city has a population, so to access the populations, I'd expect the following to work. It's not, thus my question. I broke it down into pieces to make it simpler along the way:

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

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

getPopulation() returns an integer. country is defined as List<City*> *city; Any help on how I could figure out my problem would be greatly appreciated.

edit adding more code for better idea of what I'm working with. First, 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;
};

Now, here is what might relevant in the List class..

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;
};

I have a hunch that the process of inserting might be the problem. I insert with the List class's += operator, shown in the List implementation above. It calls the private insert method shown above, as well. It looks like this:
City *somecity = new City(x,y,z); //some parameters. integers.
*city_list += somecity; // where city_list is a List.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小姐丶请自重 2024-11-03 02:18:14

我认为您遇到了变量范围问题。

您的 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. 使用引用计数智能指针来创建值 Implement ListNode 的副本,该指针将管理对象的生命周期。

I think you've got a variable scoping problem.

Your ListNode class contains a pointer to the node value. Your ListNode constructor takes in a pointer to the node value and saves it.

The problem is if that pointer is to a local variable that then goes out of scope. Your ListNode's node pointer is now pointing to an object that doesn't exist. e.g. in this example

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.

There are a couple possible remedies:

  1. Have your ListNode contain values rather than pointers. The drawback here is that you will be making copies of the values
  2. Implement ListNode using a reference counted smart pointer which will manager the lifetime of the object.
同尘 2024-11-03 02:18:14

那么,您可以做的是:

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;

希望它能帮助你。

Well, what you could do is:

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

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

It will take the existing City (on the memory) and put it at the head of the List node, and so on.

and if you want to copy them, maybe you could just make this:

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

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

Hope it will help you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文