我正在删除一个被反对的分段错误,被基类的指针引用,即使我已经声明了析构函数是虚拟的!
这是我的代码
class Shape
{
public:
virtual ~Shape()
{
cout<<"Shape destructor is called!"<<endl;
}
};
class Line : public Shape
{
public:
~Line()
{
cout<<"Line destructor is called!"<<endl;
}
};
int main()
{
Line myLine;
Shape* myShapePtr = &myLine; //Line A
delete myShapePtr;
}
`
调用行析构函数!
调用Shape析构函数!
./ runCP.sh:line 2:2915分段错误./a.out
据我所知,在A行中,对象被切片,这就是原因,我收到了这个错误。但是,我无法弄清楚对象切片如何导致分段错误。
如果对象已被切片,则不得调用虚析构函数,但此处也会调用虚析构函数。
请帮助我理解这一点。
答案 0 :(得分:13)
您只能delete
使用new
分配的对象。
myShapePtr
未指向使用new
分配的对象,它指向myLine
,这是一个局部变量。
作为本地变量,myLine
具有自动存储持续时间。当结束声明它的块的}
到达时,它将被自动销毁。
答案 1 :(得分:5)
您只能在使用delete
创建的对象上使用new
,在其他任何内容上使用delete
,包含的局部变量是未定义的行为。
答案 2 :(得分:3)
您无法删除堆栈中的对象。你必须先用new
实例化它:
Shape* MyShapePtr = new Line();
delete MyShapePtr;
答案 3 :(得分:2)
您在堆栈上声明了myLine
。在C ++中,当超出范围(}
)时,它将自动被破坏,因此删除它是错误的代码。
您应该(并且始终)对从delete
返回的内存使用new
。
答案 4 :(得分:0)
如果您将此作为面试问题,请通过重载delete operator
来安抚面试官!