您好我正在努力工作,制作一个从c ++中运行gnuplot的界面,并且由于某种原因我的链接列表实现失败。
以下代码在plots->append(&plot)
行上失败。单步执行代码,我发现由于某种原因,构造函数~John()
之后会立即调用析构函数John()
,而我似乎无法弄清楚原因。
下面的代码是仅在Plot*
上运行的精简版本。最初我将链表作为模板类。它在ll<int>
和ll<char*>
下工作正常但由于某种原因它以ll<Plot*>
失败。
请你帮我弄清楚它失败的原因?也许可以帮助我了解如何使其发挥作用?
提前:感谢一堆!
// B2S
#include <string.h>
class Plot{
char title[80];
public:
Plot(){ }
};
class Link{
Plot* element;
Link* next;
Link* prev;
friend class ll;
};
class ll{
Link* head;
Link* tail;
public:
ll(){
head = tail = new Link();
head->prev = tail->prev = head->next = tail->next = head;
}
~ll(){
while (head!=tail){
tail = tail->prev;
delete tail->next;
}
delete head;
}
void append(Plot* element){
tail->element = element;
tail->next = new Link();
tail->next->prev = tail;
tail->next = tail;
}
};
class John{
ll* plots;
public:
John(){
plots= new ll();
}
~John(){
delete plots;
}
John(Plot* plot){
John();
plots->append(plot);
}
};
int main(){
Plot p;
John k(&p);
}
答案 0 :(得分:2)
声明:
John();
只需构建一个新的无名John,它会被创建并立即销毁。没有办法(在当前版本的C ++中)从另一个构造函数或已经构造的对象调用构造函数。
这意味着您plots
John
成员的k
成员永远不会被初始化,因此当您从append
构造函数中调用John
时崩溃
[正如Neil Butterworth评论的那样,如果您实际构建了一个ll
实例,那么还有其他问题,这只是最直接的问题。]
答案 1 :(得分:2)
因为您无法在C ++中调用类似的替代构造函数。在...
John(Plot* plot){
John();
plots->append(plot);
}
您的第一行使用默认构造函数构造一个新的John
对象,然后抛弃结果。然后它会在append
上调用plots
(由于它尚未设置为任何内容,因此是垃圾邮件)。将实际的plots
初始化代码重构为私有方法,然后在执行任何其他操作之前在两个构造函数中调用此init
方法。
答案 2 :(得分:1)
head = tail = new Link();
这里指定head和tail指向同一个链接对象。由于您从未重新分配其中任何一个,这意味着每当您更改head的任何属性(例如head.next = foo
)时,都会对尾部应用相同的更改。
意思是头部和尾部将始终具有相同的元素,前身和相同的后继者。显然这不会导致预期的结果。
答案 3 :(得分:0)
Plot p;
John k(&p);
请改用:
Plot * p = (Plot*) new Plot;
John k(p);
这段代码坏了,因为一旦p超出范围,k对它的引用就会消失。这不是导致段错误的错误,但是一旦修复了其他错误,它可能会在以后导致段错误。
您需要稍后删除。