删除 c++ 中的对象

发布于 2024-12-05 07:33:50 字数 262 浏览 1 评论 0原文

我有一个 LinkedList,其中的 Node 有一个字段:

void* _data;

现在,我想删除此数据,但我不知道该数据是原始数据还是动态分配的对象。

因此,如果 write:

~Node() {
  delete _node;
}

并且数据是动态分配的对象,它会调用该对象的析构函数还是会出现内存泄漏?

那么我怎样才能做到这一点呢?

I have a LinkedList with a Node that have a field:

void* _data;

Now, I want to delete this data, but i cant know if the data will be a primitive or an object that was dynamically allocated.

so, if a write:

~Node() {
  delete _node;
}

and the data is an object that was dynamically allocated, will it call the destructor of the object or will i have a memory leak?

So how can I make this work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

慕烟庭风 2024-12-12 07:33:50

不要这样做!

void指针上调用delete是一种未定义行为[参考下面]
未定义的行为意味着任何事情都可能发生,程序有时可能会崩溃,有时可能会工作,但你无法始终预测它的行为,这是一种非常糟糕的编程方式。

正如您正确地得出的结论,void* 运算符无法确定它需要调用哪个类析构函数,最终导致未定义的行为。

那么我怎样才能完成这项工作呢?
正如我所见,您拥有一个 void* 指针的目的是为了拥有一个通用的链接列表实现。 C++已经提供了模板化的通用链接列表std::list 为此目的,您可以使用它,因为重新发明轮子没有意义,而且标准链接列表实现很可能比通用链接列表的任何自定义实现版本更好。

如果您仍然想要拥有自己的链接列表版本。您应该实现一个通用模板链接列表类,就像 std::list 所做的那样。

查看模板编程


参考:
根据C++03 标准第 5.3.5/3 节:

在第一种选择(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应是操作数动态类型的基类,并且静态类型应具有虚拟析构函数或行为未定义。在第二种选择(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则行为未定义(脚注 73)。

脚注73)

这意味着不能使用 void* 类型的指针删除对象,因为不存在 void 类型的对象

Don't do that!

Calling delete on a void pointer is an Undefined Behavior.[Reference Below]
Undefined Behavior means that anything can happen, the program might crash sometimes or might work sometimes but you cannot predict its behavior at all times, which is a very bad way of programing.

As you rightly concluded with void* there is no way that the delete operator can figure out which class destructor it needs to call, Eventually, leading to a Undefined Behavior.

So how can i make this work?
As I see Your intention of having an void* pointer is for having a generic Link list implementation. C++ already provides a templated generic link list std::list for this purpose, You can use it as there is no point in re-inventing the wheel and it is most likely that the standard link list implementation will be better than any custom implemented version of a generic link list.

If you would still want to have your own version of the link list. You should implement a generic template link list class just what std::list does.

Have a look at Template Programming.


Reference:
As per C++03 Standard section 5.3.5/3:

In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined(FootNote 73).

Foot Note 73)

This implies that an object cannot be deleted using a pointer of type void* because there are no objects of type void

陪你搞怪i 2024-12-12 07:33:50

如果您需要此行为,请使用模板。正如所写的,您的代码无法知道要调用哪个析构函数。

If you need this behavior, use a template. You code, as written, has no way to know what destructor to call.

意中人 2024-12-12 07:33:50

_node 的类型为 void* 时,delete _node 始终不正确,因为与 delete 一起使用的操作数的类型必须始终是指向所构造对象的动态类型的指针,或者指向作为该类型的基类的类型的指针,前提是基类类型具有虚拟析构函数。显然,void* 无法满足该要求的任何一部分。

如果您使用的是 void*,则需要在调用 delete 之前找到某种方法将其转换回原始类型。另一种方法是使用类似于 std::shared_ptr的方法,它可以在构造(或重置)时存储适当的删除器,并自动调用节点被破坏。

When _node has type void*, delete _node is always incorrect because the type of the operand used with delete must always be a pointer to the dynamic type of the object constructed, or to a type that is a base class of that type, providing that the base class type has a virtual destructor. Clearly, void* cannot fulfil either part of that requirement.

If you are using a void* you need to find someway of casting back to the original type before calling delete. An altenrative approach would be to use something like a std::shared_ptr<void> which can be used in a way where an appropriate deleter is stored at construction (or reset) time and will automatically be called with the node is destroyed.

梦醒灬来后我 2024-12-12 07:33:50

删除 void 指针是危险的。编译器可能会警告或拒绝您的代码。 C++ 标准规定您不应该这样做。

实际上,如果编译器确实接受您的代码,它只会释放内存而不调用析构函数。

Deleting a void pointer is dangerous. Compilers may warn or reject your code. The C++ standard says you shouldn't be doing so.

In practice, if the compiler does accept your code, it only frees the memory without calling the destructor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文