-1

我在一个名为的文件中有这个简单的代码virtual.cpp

#include <iostream>


class Parent
{
    public:
    virtual ~Parent(){ std::cout << "Parent Destructor" << std::endl; }

    virtual void VirtualFunction()
    {
        std::cout << "VirtualFunctionInParent" << std::endl;
    }
};

class Child: public Parent
{
    public:
    virtual ~Child() { std::cout << "Child Destructor" << std::endl; }
    virtual void VirtualFunction()
    {
        std::cout << "VirtualFunctionInChild" << std::endl;
    }    
};

int main()
{
    Child child1;
    Parent *parent1 = &child1;
    delete parent1;

}

它编译正确

g++ -Wall --pedantic -o virtual virtual.cpp 

但是当我运行它时,我得到了这个错误:

./virtual 
Child Destructor
Parent Destructor
free(): invalid pointer
Annullato (core dump creato)

我认为这是因为我删除了指针 parent1,所以这会擦除指针指向的内存,即&child1. 因此,当 child1 超出范围时, Child 析构函数尝试释放不再存在的内存。

我的问题:

  1. 我的推理正确吗?
  2. 如果我的推理是正确的,那么处理这种“超出范围”情况的正确方法是什么?
4

4 回答 4

3

我删除了指针 parent1,所以这会擦除指针指向的内存。我的推理正确吗?

不,您正在从删除中获得核心转储。

只有返回的地址new可以传递给delete.

delete不会擦除内存,因为内存没有“已擦除”状态的概念。

这是处理这种“超出范围”情况的正确方法?

删除delete线。这不是必要的。

当该范围离开时,在范围内创建的任何变量都会被自动管理。

于 2021-06-08T20:16:26.457 回答
1

不要调用delete你没有分配的对象new。这个对象会在超出范围时被删除,所以没有什么特别的方法可以正确地销毁它。

如果您希望对象在范围内开始其生命周期并在范围结束时结束其生命周期,请不要使用newand delete。只需正常声明它们即可。

newanddelete用于要管理其生命周期的对象。分配它们new并在完成后调用delete它们。

于 2021-06-08T20:15:54.750 回答
1

首先是您不使用new或任何其他方式来分配动态内存的事实。所以没有使用的意义delete

要回答您的下一个问题,您必须首先告诉我们为什么要在子地址上创建父指针?

于 2021-06-08T20:16:40.180 回答
1

更具体地回答您的问题

  1. 我的推理正确吗?

您永远不会超出范围,因为您在 main() 中将变量声明到当前堆栈帧。为了将变量声明到堆(超出范围),您必须使用动态内存分配。

Parent * parent1 = new(Child);
delete(parent1);

这段代码所做的是在堆中创建一个子类,然后在有效指向子类的范围内创建一个本地的 parent1 指针。

于 2021-06-10T00:26:03.680 回答