0

我有一个通用链表,它适用于各种类型的数据,包括对象和指向对象的指针等,但是当我从派生自抽象类的类中插入对象时,我无法使用该列表。

我有一个名为vehicle 的抽象类和2 个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);

我有错误:

无法分配抽象类型“车辆”的对象

并且编译器显示错误出现在我编写的部分链表代码的 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++;
    }
}
4

3 回答 3

5

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

这是您看到的错误的原因是您在此处取消引用您的指针:lv.insertEnd(*v1). 以这种方式传入一个值将导致 C++ 使用 中指定的类型的复制构造函数insertEnd来使对象在你的insertEnd函数内部(检查你的代码:参数insertEnd的类型肯定是你的模板中指定的类型 - 这是vehicle这里)。通过值传递,您是在告诉您的代码将整个 of 复制v1insertEnd. 这分崩离析,因为vehicle它是一个抽象类:它的复制构造函数不能用于创建一个功能齐全的对象,因为它是抽象的。

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

编辑:在看到您添加的 insertEnd 代码(通过引用传递的地方)后,有一个附录:编译器不会insertEnd. 相反,您可能会在这一行看到错误:newNode->item = new Item. 在这里,您可以看到您尝试实例化抽象类的位置。将单词 ' Item' 替换为 ' vehicle' - 这就是您使用模板所做的 - 您可以非常清楚地看到它。

无论如何,通过引用传递给取消引用的指针确实是一件非常痛苦且容易出错的事情。引入错误太容易了:如果你delete在代码中的任何地方 v1,就像一个优秀的程序员所做的那样(伟大的程序员使用自动指针),你可能会让你的引用悬空:有一天指向内存中的一个空间——比如当某人重要的是运行您的代码 - 可能在您的参考不知情的情况下充满垃圾。这就是发疯的方式,我的朋友。

这就是为什么智能指针是 C++ 程序员最好的朋友的原因:一旦你理解了它们在做什么,你几乎可以忽略这种混乱,只是通过自由地传递它们。他们的生命周期契约定义得很好,他们自己清理,他们是异常安全的。只要您不设置引用周期 - 这在日常使用中比通过引用传递取消引用的指针问题要小得多 - 或尝试在标准容器中使用 auto_ptr 请阅读此链接并理解它,你已经大大减少了你的记忆问题。

于 2013-01-07T01:47:11.253 回答
2

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

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

在您的list<vehicle> lv;中,lv仅包含vehicle类型对象,lv.insertEnd(*v1);会将您的对象切片为车辆类型,这是不允许的,因为车辆是抽象类。

于 2013-01-07T01:47:07.930 回答
1

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

此外,stl 的复制构造语义不支持多态使用。“车辆”列表应该只包含车辆对象,而不是汽车对象。

您必须使用指针容器。

于 2013-01-07T01:50:08.347 回答