繁体   English   中英

如何删除空指针?

[英]How to delete void pointer?

在 C++ 中删除这样的对象有什么问题吗?

MyCls* c = new MyCls();
void* p = (void*)c;
delete (MyCls*)p;

这书面是合法的。

回到MyCls*至关重要。 否则,您将调用未定义的行为——将不会调用 MyCls 析构函数,并且还可能出现其他问题(例如崩溃)。 您必须转换回正确的类型。

另请注意,如果涉及多重继承并使用多重转换,这可能会很复杂。 您的演员必须在任一方向“匹配”。

如果您的代码结构使得您在销毁时不知道类型,请为每个可删除对象提供一个带有虚拟析构函数的公共基类。 然后在调用 delete 之前转换回基类。

代码定义明确。 两种类型转换都是静态类型转换,尽管使这种类型显式( static_cast<void*>)而不是使用 C 样式类型转换是一种很好的风格。 该标准表示,如果指向对象的指针被转换为空指针并通过静态转换返回,它将保持其原始值。 因此,您的最终delete表达式应具有与delete c相同的效果。

话虽如此,使用void*通常是 C++ 中的代码异味。

删除后将指针设置为nullptr是一个好习惯,尤其是为了避免在另一个线程/事件处理程序中访问冲突/段错误。

auto c = new MyCls();
auto p = static_cast<void*>c;
delete static_cast<MyCls*>p;
p = nullptr;
c = nullptr;

使用智能指针甚至完全避免new / delete更好。

{
    auto c = std::make_unique<MyCls>();
    auto p = static_cast<void*>(c.get());
    // no need to delete p
} // c will be released automatically during unwinding

在C ++中,首选显式强制类型转换为static_cast

如果~MyCls()是非平凡的,那么它将被调用,因为你将pMyCls* 删除void*不会调用析构函数,这可能会导致内存泄漏或其他问题。

尽管此代码有效,但这不是一个好习惯。

作为一般准则,在野外不应该有new s 和delete s。 尝试强制执行只有构造函数可以调用new并且只有析构函数可以调用delete的规则,这将有助于您更好地组织代码。

如果您使用的是 C++11,请始终尝试std::shared_ptr等,这将自动为您执行上述操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM