1
#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 指向的被删除了。当我删除未发生动态继承时指向派生类的基类指针时,它是如何工作的?对不起我的英语不好。

4

3 回答 3

4

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

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

于 2012-04-19T13:53:42.867 回答
0

对以下代码有什么期望

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

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

于 2012-04-19T13:54:14.257 回答
-1

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

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

  1. 复制构造函数
  2. 赋值运算符
  3. 虚拟析构函数

前两个与制作“深拷贝”有关,而第三个是我们所关心的。

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

所以:

class A
{
    public A(A & copy) { ... }
    public static A & operator = (A & rhs) { ... }
    virtual ~A() { ... }
}

class B : A { } // inherits A's destructor via virtual table
于 2012-04-19T13:56:56.033 回答