指针、智能指针还是共享指针?
我正在使用普通指针编程,但我听说过像 Boost 这样实现智能指针的库.我也看到在 Ogre3D 渲染引擎中深入使用了共享指针.
I am programming with normal pointers, but I have heard about libraries like Boost that implement smart pointers. I have also seen that in Ogre3D rendering engine there is a deep use of shared pointers.
这三者究竟有什么区别,我应该坚持只使用其中的一种吗?
What exactly is the difference between the three, and should I stick on using just a type of them?
推荐答案
Sydius 很好地概述了类型:
Sydius outlined the types fairly well:
- 普通指针就是这样――它们指向内存中某处的某些东西.谁拥有它?只有评论会让你知道.谁释放它?希望主人在某个时候.
- 智能指针是一个涵盖多种类型的总称;我假设您指的是使用 RAII 模式的范围指针.它是一个封装了指针的堆栈分配对象;当它超出范围时,它会在它包装的指针上调用 delete.它拥有"包含的指针,因为它负责在某个时刻删除它.它们允许您获得对它们包装的指针的原始引用以传递给其他方法,以及释放指针,允许其他人拥有它.复制它们没有意义.
- 共享指针 是一个堆栈分配的对象,它包装了一个指针,这样您就不必知道谁拥有它.当内存中对象的最后一个共享指针被销毁时,包装的指针也将被删除.
- Normal pointers are just that - they point to some thing in memory somewhere. Who owns it? Only the comments will let you know. Who frees it? Hopefully the owner at some point.
- Smart pointers are a blanket term that cover many types; I'll assume you meant scoped pointer which uses the RAII pattern. It is a stack-allocated object that wraps a pointer; when it goes out of scope, it calls delete on the pointer it wraps. It "owns" the contained pointer in that it is in charge of deleteing it at some point. They allow you to get a raw reference to the pointer they wrap for passing to other methods, as well as releasing the pointer, allowing someone else to own it. Copying them does not make sense.
- Shared pointers is a stack-allocated object that wraps a pointer so that you don't have to know who owns it. When the last shared pointer for an object in memory is destructed, the wrapped pointer will also be deleted.
什么时候应该使用它们呢?您将大量使用作用域指针或共享指针.您的应用程序中有多少线程正在运行?如果答案是可能很多",那么如果到处使用共享指针,就会成为性能瓶颈.原因是创建/复制/销毁共享指针需要是一个原子操作,如果您有许多线程在运行,这可能会影响性能.但是,情况并非总是如此 - 只有测试才能确定.
How about when you should use them? You will either make heavy use of scoped pointers or shared pointers. How many threads are running in your application? If the answer is "potentially a lot", shared pointers can turn out to be a performance bottleneck if used everywhere. The reason being that creating/copying/destructing a shared pointer needs to be an atomic operation, and this can hinder performance if you have many threads running. However, it won't always be the case - only testing will tell you for sure.
有一个反对共享指针的论点(我喜欢) - 通过使用它们,您允许程序员忽略谁拥有指针.这可能会导致循环引用的棘手情况(Java 会检测到这些,但共享指针不能)或大型代码库中的一般程序员懒惰.
There is an argument (that I like) against shared pointers - by using them, you are allowing programmers to ignore who owns a pointer. This can lead to tricky situations with circular references (Java will detect these, but shared pointers cannot) or general programmer laziness in a large code base.
使用作用域指针有两个原因.第一个是用于简单的异常安全和清理操作――如果你想保证一个对象无论遇到什么异常都会被清理,并且你不想堆栈分配那个对象,把它放在一个作用域指针中.如果操作成功,您可以随意将其转移到共享指针,但同时使用作用域指针节省开销.
There are two reasons to use scoped pointers. The first is for simple exception safety and cleanup operations - if you want to guarantee that an object is cleaned up no matter what in the face of exceptions, and you don't want to stack allocate that object, put it in a scoped pointer. If the operation is a success, you can feel free to transfer it over to a shared pointer, but in the meantime save the overhead with a scoped pointer.
另一种情况是当您想要明确的对象所有权时.有些团队喜欢这个,有些则不喜欢.例如,数据结构可能返回指向内部对象的指针.在作用域指针下,它将返回一个应被视为弱引用的原始指针或引用 - 在拥有它的数据结构被破坏后访问该指针是错误的,而删除它是错误的.在共享指针下,如果有人仍然持有它的句柄,则拥有对象无法破坏它返回的内部数据 - 这可能会使资源打开的时间比必要的长得多,或者更糟,具体取决于代码.
The other case is when you want clear object ownership. Some teams prefer this, some do not. For instance, a data structure may return pointers to internal objects. Under a scoped pointer, it would return a raw pointer or reference that should be treated as a weak reference - it is an error to access that pointer after the data structure that owns it is destructed, and it is an error to delete it. Under a shared pointer, the owning object can't destruct the internal data it returned if someone still holds a handle on it - this could leave resources open for much longer than necessary, or much worse depending on the code.
相关文章