删除基类的指针时,“删除”的工作原理

时间:2012-04-19 13:47:50

标签: c++

#include <iostream>

using namespace std;
int *p1;
struct base
{
    base():a(10){}
    int a;
    ~base()
    {
        cout << "~base()\n";
    }
};

struct derive:public base
{
    derive():b(5){

        p1=&b;
        cout << p1 << "\n";

    }
    int b;
    ~derive()
    {
        cout << "~derive()\n";
    }
};
int main()
{
    base *p = new derive;
    delete(p);
    cout << *p1;
    return 0;
}

我认为派生的b不会被删除,但p1指向的内容被删除了。 当我没有动态继承发生时删除指向派生类的基类的指针时它是如何工作的? 对不起我的英文。

3 个答案:

答案 0 :(得分:4)

未定义的行为,因为基类析构函数不是virtual。 UB意味着任何事情都会发生。

如果基类没有虚析构函数,请不要通过基类删除派生对象。

答案 1 :(得分:0)

人们对以下代码的期望是什么

base *p = new derive;
delete(p);

是p正确指向的派生对象。 这只能在基类具有虚拟析构函数时完成。这不是这里的情况,所以在derive析构函数中发生的任何清理都不会发生,这是一种不健康的情况(或者更为技术性地说是Luchian:未定义的行为)。

答案 2 :(得分:-1)

我不是100%我理解这个问题,因为我使用了c ++已经有一段时间了,但我会试一试。

一般来说,如果你有一个动态分配的对象,你需要有三件事,我的老师曾经称之为“邪恶三部曲”。

  1. 复制构造函数
  2. 作业运营商
  3. 虚拟析构函数
  4. 前两个与制作“深拷贝”有关,而第三个则是我们所关注的。

    您需要将析构函数标记为虚拟,以将其添加到对象虚拟表中,这样析构函数就会调用链。

    这样:

    class A
    {
        public A(A & copy) { ... }
        public static A & operator = (A & rhs) { ... }
        virtual ~A() { ... }
    }
    
    class B : A { } // inherits A's destructor via virtual table