【问题标题】:Is it safe to delete a POD object by a pointer to its base?通过指向其基的指针删除 POD 对象是否安全?
【发布时间】:2015-07-02 17:23:37
【问题描述】:

实际上,我正在考虑可破坏的对象,而不仅仅是POD(我不确定 POD 是否可以具有基类)。

当我从 cppreference 阅读 is_trivially_destructible 的解释时,我注意到了这一点:

被普通可破坏对象占用的存储空间可以在不调用析构函数的情况下被重用。

所以,这样做是安全的:

struct A {
  int a;
};
struct B : A {
  int b;
};
int main() {
  A* a = new B;
  delete a;
}

B::~B() 不会被调用 - 并且 AFAIK(如果我错了,请更正)整个内存将被释放。而B::~B() 肯定是微不足道的。

我知道这段代码很难闻,但我的问题只是关于这段代码的安全性......

【问题讨论】:

  • 您确定a 将始终指向B 实例并且B 将保持微不足道的可破坏性吗?如果有人修改了B 或将其替换为B 的不易破坏的子类,他将默默地引入一个错误。
  • 我不太明白你的目标。如果你想重用一个堆分配的对象,你不会释放堆内存(伴随着 delete 调用),但你会将未使用的实例保留在某种回收容器中,而不是在其上调用 delete。您可能还会有一个“工厂”方法来获取实例,该方法首先会尝试回收旧实例,然后再使用新实例创建新实例。
  • 刮开我以前的帖子哈哈。他问他是否需要一个虚拟析构函数而不使用这些词:)
  • @Kos - 不是我不确定。你是对的 - 这将是一个错误。但是对于这个问题,假设所有涉及的类型都可以简单地破坏。
  • 如果它使用继承,它是否仍然是POD?

标签: c++ c++11 destructor


【解决方案1】:

不,这是不允许的。 [expr.delete]/p3,强调我的:

在第一种选择(delete object)中,如果 要删除的对象与其动态类型不同,静态 type 应该是对象的动态类型的基类 删除并且静态类型应该有一个虚拟析构函数或者 行为未定义。

事实上,委员会最近rejecteda proposal to make deleting a POD via a pointer-to-base well-defined

【讨论】:

  • 也许值得一提的是显式调用::operator delete(a) 是否是一种有效的解决方法。据我所知,这是有效的。不过,如果delete a; 有可能实际上调用了不同的operator delete,我不会推荐它。
猜你喜欢
  • 2012-02-05
  • 1970-01-01
  • 2010-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多