链表-插入对象

c++ Linked List - Insert Object

本文关键字:对象 插入 链表      更新时间:2023-10-16

我有一个通用的链表,与各种类型的数据,包括对象和指针对象等工作,但我有麻烦与列表工作时,我从一个类,从抽象类派生的插入对象。

我有一个抽象类vehicle和两个类carr和truck,我可以这样做:

list<vehicle> lv;
vehicle * v1;
vehicle * v2;
v1 = new carr;
v2 = new truck;
cin >> *v1 >> *v2;
//But when I try to insert in the list
lv.insertEnd(*v1);

我有错误:

不能分配抽象类型'vehicle'的对象

编译器显示错误是在我的链表代码的insertEnd方法中,在我写的部分:

newNode->item = new Item;

这是一个项目的一部分,我需要有一个车辆列表,车辆可以是汽车,卡车等。我有一组车辆实现与指针到指针,但我正试图做到这一点与车辆列表。

你能帮我吗?

编辑:项目在我的链表中,我将显示我的insertEnd方法:

template <class Item>
void list<Item>::insertEnd(const Item& item)
{
    node<Item> *newNode= new node<Item>;
    newNode->item = new Item;
    *(newNode->item) = item;
    newNode->next = 0;
    if(head == 0)
    {
       head = newNode;
       tail = newNode;
        _size++;
    }
    else
    {
        novoNo->prev = tail;
        tail->next = newNode;
        tail = newNode;
         _size++;
    }
}

您正在尝试按值在链表中存储项。按值使用项打破了多态性:只有指针或引用是多态的。

你看到这个错误的原因是你在这里解引用你的指针:lv.insertEnd(*v1)。以这种方式传递值将导致c++使用insertEnd 中指定类型的复制构造函数来创建insertEnd函数内部的对象(检查您的代码:insertEnd参数的类型肯定是模板中指定的类型-这里是vehicle)。通过按值传递,您告诉代码将整个v1复制到insertEnd内部的新对象中。这就行不通了,因为vehicle是一个抽象类:它的复制构造函数不能用来创建一个功能完整的对象,因为它是抽象的。

这有点掩盖了这里真正发生的事情:你不能通过值传递对象并期望它们是多态的。如果没有看到此错误,可能会发生的情况是,您可能会对对象进行切片,这可能更不利于调试。按照@billz的建议,使用智能指针。

编辑:在看到您添加的insertEnd代码后,您通过引用传递,有一个附录:编译器将调用insertEnd中的复制构造函数。相反,您可能会在这一行看到错误:newNode->item = new Item。在这里,您可以看到您正在尝试实例化抽象类的位置。将"Item"替换为"vehicle"——这就是你对模板所做的——你可以很清楚地看到它。

无论如何,按引用传递到解引用指针确实是一件非常痛苦且容易出错的事情。这很容易引入错误:如果在代码中的任何地方使用delete v1,就像一个优秀的程序员所做的那样(优秀的程序员使用自动指针),那么您可能会让引用晃来晃去:指向内存中的某个空间,有朝一日——比如某个重要的人正在运行您的代码时——可能会在引用不知情的情况下被垃圾填充。这是通往疯狂之路,我的朋友。

这就是为什么智能指针是c++程序员最好的朋友:一旦你理解了它们在做什么,你几乎可以忽略这种混乱,只是通过值自由地传递它们。它们的生命周期契约定义得很好,它们自己清理,它们是异常安全的。只要你不设置引用周期——这在日常使用中比通过引用传递解引用指针的问题要少得多——或者尝试在标准容器中使用auto_ptr,你就大大减少了内存问题。

在这种情况下你需要使用指针,更好的方法是使用智能指针。

std::list<std::shared_ptr<vehicle> > lv;

在你的list<vehicle> lv;, lv只包含vehicle类型的对象,lv.insertEnd(*v1);切片你的对象到车辆类型,这是不允许的,因为车辆是抽象类

由于不能实例化抽象类型的对象,因此无法构造插入对象。

同样,stl的复制构造语义不支持多态使用。"vehicle"列表应该只包含vehicle对象,而不是car对象。

必须使用指针容器。