4

考虑以下代码:

class A 
{
public:
  A() {}
  ~A() {}
};

class B: public A
{
  B() {}
  ~B() {}
};

A* b = new B;
delete b; // undefined behaviour

我的理解是 C++ 标准说删除 b 是未定义的行为 - 即,任何事情都可能发生。但是,在现实世界中,我的经验是 ~A()总是被调用,并且内存被正确释放。

如果 B 引入任何具有自己的析构函数的类成员,它们将不会被调用,但我只对上述简单的情况感兴趣,其中使用继承可能修复源代码所在的一个类方法中的错误不可用。

显然,在非平凡的情况下,这不会是您想要的,但至少是一致的。对于显示的代码,您是否知道没有发生上述情况的任何C++ 实现?

4

4 回答 4

6

这是 C++ 标签中一个永无止境的问题:“什么是可预测的未定义行为”。自己轻松解决所有问题:获取每个C++ 编译器实现并检查可预测的不可预测是否仍然有效。然而,这是你必须自己做的事情。

发回您发现的内容,这将非常有用。只要不可预测的行为具有一致的和注释的行为。这让编写 C++ 编译器的人很难让任何人关注他的产品。按照惯例,标准化经常发生在具有许多未定义行为的语言

于 2010-12-23T22:59:20.160 回答
3

据我所知,没有不正确的实现。另一方面,如果有一个类,如果你在其中放入一个非 POD,它就会爆炸,这是一种坏事,将其描述为 bug 几乎是不合理的。

此外,您的问题标题具有令人难以置信的误导性。是的,不调用类的析构函数是一个严重的现实问题。是的,如果您将输入集限制为极少数的真实世界类,那不是问题。

于 2010-12-23T22:50:58.180 回答
1

“对于显示的代码”,您不太可能找到会起作用的实现。也就是说,如果我们将各种“调试”实现排除在外,这些实现是专门为捕获此类错误而设计的。

于 2010-12-23T22:46:47.623 回答
1

在非平凡的情况下,B 类几乎总是比 A 大,因为它里面有一个 A 的实例以及 B 的其他成员。当你引入虚拟成员时,情况会变得更糟。

所以虽然 ~A 会被调用,但很容易看出这种事情会导致内存泄漏。这是未定义的行为,不是因为它可能不会调用〜A,这基本上是有保证的,而是取决于内存的管理方式。

于 2010-12-23T22:51:05.813 回答