使用智能指针实现容器 [英] Implementing Containers using Smart Pointers
问题描述
好吧,所以每个人都知道应该避免像瘟疫一样避免使用原始指针,而应该使用智能指针,但是这种建议在实现容器时是否适用?这是我要完成的工作:
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 AVLTreeNode
s, 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屋!