使用智能指针实现容器 [英] Implementing Containers using Smart Pointers

查看:115
本文介绍了使用智能指针实现容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,所以每个人都知道应该避免像瘟疫一样避免使用原始指针,而应该使用智能指针,但是这种建议在实现容器时是否适用?这是我要完成的工作:

Ok, so everyone knows that raw pointers should be avoided like the plague and to prefer smart pointers, but does this advice apply when implementing a container? This is what I am trying to accomplish:

template<typename T> class AVLTreeNode {
public:
    T data;
    unique_ptr<AVLTreeNode<T>> left, right;
    int height;
}

Unique_ptr可以使容器函数的编写更加麻烦,因为我不能拥有多个原始指针以一种优雅的方式临时指向同一对象。例如:

Unique_ptr can make container functions more cumbersome to write because I can't have multiple raw pointers temporarily pointing to the same object in a way that is elegant. For example:

unique_ptr<AVLTreeNode<T>> rotate_right(unique_ptr<AVLTreeNode<T>> n1)
{
    unique_ptr<AVLTreeNode<T>> n2 = n1->left;

    n1->left = n2->right;
    n2->right = n1;
    // n1 must now be referenced through the longer name n2->right from now on
    n2->right->recalculate_height();
    n2->recalculate_height();

    return n2;
}

(在这个例子中这没什么大不了的,但是我可以想象成为一个问题)。我是否应该将此类问题作为一个有力的暗示,即应该使用旧的删除和原始的容器来实现指针?只是为了避免编写析构函数,这似乎很麻烦。

(It's not a big deal in this example but I can imagine how it could become a problem). Should I take problems like these as a strong hint that containers should be implemented with good old new, delete, and raw pointers? It seems like awfully a lot of trouble just to avoid writing a destructor.

推荐答案

实现容器时,我通常不使用智能指针如您所示。像瘟疫一样避免不要原始指针(imho)。要强制执行内存所有权时,请使用智能指针。但是通常在容器中,容器拥有构成数据结构的指针所指向的内存。

I do not usually use smart pointers when implementing containers as you show. Raw pointers (imho) are not to be avoided like the plague. Use a smart pointer when you want to enforce memory ownership. But typically in a container, the container owns the memory pointed to by the pointers making up the data structure.

如果在您的设计中使用 AVLTreeNode 唯一拥有其左右子节点,您想用 unique_ptr 表示这一点,这很好。但是,如果您希望 AVLTree 拥有所有 AVLTreeNode s,并使用原始指针这样做,那同样有效(也是我通常的编码方式。)

If in your design, an AVLTreeNode uniquely owns its left and right children and you want to express that with unique_ptr, that's fine. But if you would prefer that AVLTree owns all AVLTreeNodes, and does so with raw pointers, that is just as valid (and is the way I usually code it).

相信我,我不是反智能指针。我是发明 unique_ptr 的人。但是 unique_ptr 只是工具框中的另一个工具。在工具箱中拥有好的智能指针并不能解决所有问题,盲目使用它们不能代替精心设计。

Trust me, I'm not anti-smart-pointer. I am the one who invented unique_ptr. But unique_ptr is just another tool in the tool box. Having good smart pointers in the tool box is not a cure-all, and using them blindly for everything is not a substitute for careful design.

更新回应评论(评论框太小):

Update to respond to comment (comment box was too small):

我经常使用原始指针(很少使用原始指针)。开源项目 libc ++ 中提供了很好的我的编码样式的示例。可以在浏览SVN链接下浏览源代码。

I use raw pointers a lot (which are rarely owning). A good sampling of my coding style exists in the open source project libc++. One can browse the source under the "Browse SVN" link.

我宁愿出于对安全性的异常考虑,每次分配资源都可以在析构函数中进行分配。 ,即使通常的解除分配发生在析构函数之外。当分配由单个指针拥有时,智能指针通常是工具框中最方便的工具。当分配由大于指针的东西(例如容器或类 Employee )拥有时,原始指针通常是组成较大对象的数据结构中的便捷部分

I prefer that every allocation of a resource be deallocate-able in a destructor somewhere, because of exception safety concerns, even if the usual deallocation happens outside of a destructor. When the allocation is owned by a single pointer, a smart pointer is typically the most convenient tool in the tool box. When the allocation is owned by something larger than a pointer (e.g. a container, or a class Employee), raw pointers are often a convenient part of the data structure composing the larger object.

最重要的是,我永远不会在不知道对象拥有该资源的情况下分配任何资源,无论是智能指针,容器还是其他。

The most important thing is that I never allocate any resource without knowing what object owns that resource, be it smart pointer, container, or whatever.

这篇关于使用智能指针实现容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆