【问题标题】:Crashed when i delete a c++ object [duplicate]当我删除 C++ 对象时崩溃 [重复]
【发布时间】:2011-05-09 20:56:35
【问题描述】:

可能重复:
When to use virtual destructors?


[第二次讨论] 嗨,大家好!你们都在谈论虚拟析构函数。 我还考虑了基类的析构函数。 但另一个测试是这样的: A级 { 民众: 一种() { } 虚空乐趣() { } 私人的: 诠释mIntA; };

当 A 类有一个虚拟函数(不是虚拟目标函数)时, 没关系。删除ptrA就OK了!

所以,我认为 A 只需要一个 vptr 来激活多态。不是A类s destructor must be virtual. Class As析构函数不是虚拟的就可以使资源不被释放 正确。


class A
{
 public:
  A()
  {
  }
  /*virtual*/ ~A()
  {
  }
 private:
  int mIntA;
};

class B : public A
{
public:
 B()
 {
  mIntB = 1234;
 }

 virtual ~B()
 {
  int i = 0;
 }

private:
 int mIntB;
};

我有一个 A 类。还有一个从 A 派生的 B 类; A 没有任何虚函数。 所以当我这样做时:

A* ptrA = new B;
delete ptrA;

它崩溃了!

但是当给 A 添加一个虚拟的乐趣时,没关系。 我们知道,ptrA 是一个 B 对象。 但这是为什么呢?

【问题讨论】:

  • it crashes! 因为未定义的行为意味着任何事情都可能发生。
  • 基本上,您不了解虚拟析构函数以及为什么需要在基类中使用它们。人们所说的完全重复的问题并不完全正确。但它的所有答案都会回答你的问题。

标签: c++


【解决方案1】:

A 类不是多态的,因此 delete 不可能知道 ptrA 实际上指向已分配的块内,因此释放会崩溃。

【讨论】:

    【解决方案2】:

    你有一个non-virtual destructor

    (这意味着当调用析构函数时,调用的是 A 的析构函数,而不是 B 的析构函数,即使对象被分配为 B)

    【讨论】:

    • 因为 OP 调用了未定义的行为,恶魔从 OP 的鼻子里飞了出去。 - everything2.com/title/demons+fly+out+your+noseen.wikipedia.org/wiki/…
    • @Omni 嗯?这到底是什么未定义?
    • @Let_Me_Be - 在派生类的对象上调用基类的析构函数。请参阅此处的第 20.7 项:parashift.com/c++-faq-lite/virtual-functions.html
    • @Let_Me_Be - 不,在你这样做的所有情况下它都是未定义的。 delete 不等同于 free。编译器没有理由在 C++ 中存储已分配块的大小,而且无论如何,指向派生类内部基类实例的指针可能由于多种原因不指向块的开头。跨度>
    • @Let_Me_Be - 删除无效指针的定义不明确。为它定义的唯一无效指针在删除它时会发生什么是空指针。是的,指向基类的指针必须指向基类的开头,但它不必指向它所属的派生类的开头。举一个明显的例子......你可以在没有你知道的虚函数的情况下进行多重继承。
    猜你喜欢
    • 2015-02-06
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多