wor*_*d87 0 c++ list insert object abstract
我有一个通用的链表,可以处理各种类型的数据,包括对象和指向对象的指针等,但是当我从一个派生自抽象类的类中插入对象时,我无法使用该列表.
我有一个名为vehicle的抽象类和2个carr和卡车类,我可以这样做:
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);
Run Code Online (Sandbox Code Playgroud)
我有错误:
不能分配抽象类型'车辆'的对象
并且编译器显示错误是在我编写的部分中的链表代码的insertEnd方法中:
newNode->item = new Item;
Run Code Online (Sandbox Code Playgroud)
这是一个项目的一部分,我需要有一个车辆列表,车辆可以是卡车,卡车等.我有一组车辆实施指针指针,但我试图用一个车辆列表这样做.
你能帮助我吗?
编辑:该项目在我的链接列表中,我将显示我的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++;
}
}
Run Code Online (Sandbox Code Playgroud)
您试图按值在链表中存储项目.按值使用项打破多态:只有指针或引用是多态的.
这是你看到的错误的原因是你在这里取消引用你的指针: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请仔细阅读并了解它,你已经大大减少了你的记忆问题.