下面这组指针之间有什么区别?什么时候在生产代码中使用每个指针?

例子将不胜感激!

scoped_ptr 要查看 weak_ptr intrusive_ptr

在产品代码中使用boost吗?


Scoped_ptr是最简单的。一旦超出范围,就会被摧毁。以下代码是非法的(scoped_ptrs是不可复制的),但将说明一点:

std::vector< scoped_ptr<T> > tPtrVec;
{
     scoped_ptr<T> tPtr(new T());
     tPtrVec.push_back(tPtr);
     // raw T* is freed
}
tPtrVec[0]->DoSomething(); // accessing freed memory

Shared_ptr是引用计数。每次发生复制或赋值操作时,引用计数都会增加。每次触发实例的析构函数时,原始T*的引用计数都会递减。一旦它为0,指针就会被释放。

std::vector< shared_ptr<T> > tPtrVec;
{
     shared_ptr<T> tPtr(new T());
     // This copy to tPtrVec.push_back and ultimately to the vector storage
     // causes the reference count to go from 1->2
     tPtrVec.push_back(tPtr);
     // num references to T goes from 2->1 on the destruction of tPtr
}
tPtrVec[0]->DoSomething(); // raw T* still exists, so this is safe

Weak_ptr是对共享指针的弱引用,需要检查指向的shared_ptr是否仍然存在

std::vector< weak_ptr<T> > tPtrVec;
{
     shared_ptr<T> tPtr(new T());
     tPtrVec.push_back(tPtr);
     // num references to T goes from 1->0
}
shared_ptr<T> tPtrAccessed =  tPtrVec[0].lock();
if (tPtrAccessed[0].get() == 0)
{
     cout << "Raw T* was freed, can't access it"
}
else
{
     tPtrVec[0]->DoSomething(); // raw 
}

Intrusive_ptr通常用于必须使用第三方智能PTR的情况。它将调用一个自由函数来增加和减少引用计数。有关更多信息,请参阅boost文档的链接。


我赞同关于查看文件的建议。这并不像看起来那么可怕。还有一些简短的提示:

scoped_ptr - a pointer automatically deleted when it goes out of scope. Note - no assignment possible, but introduces no overhead intrusive_ptr - reference counting pointer with no overhead of smart_ptr. However the object itself stores the reference count weak_ptr - works together with shared_ptr to deal with the situations resulting in circular dependencies (read the documentation, and search on google for nice picture ;) shared_ptr - the generic, most powerful (and heavyweight) of the smart pointers (from the ones offered by boost) There is also old auto_ptr, that ensures that the object to which it points gets destroyed automatically when control leaves a scope. However it has different copy semantics than the rest of the guys. unique_ptr - will come with C++0x

编辑回复: 是的


在任何关于boost智能指针的调查中,都不要忽视boost::ptr_container。在std::vector<boost::shared_ptr<T> >太慢的情况下,它们是非常宝贵的。


智能指针的基本属性

当你有属性可以分配给每个智能指针时,这很容易。有三个重要的性质。

完全没有所有权 所有权转让 所有权份额

第一个意味着智能指针不能删除对象,因为它不拥有对象。第二种方法意味着只能有一个智能指针同时指向同一个对象。例如,如果智能指针要从函数返回,则所有权将转移到返回的智能指针。

第三个意味着多个智能指针可以同时指向同一个对象。这也适用于原始指针,但是原始指针缺乏一个重要的特性:它们不定义它们是否拥有。如果每个所有者都放弃该对象,共享所有权智能指针将删除该对象。这种行为经常被需要,所以共享拥有智能指针被广泛使用。

一些智能指针既不支持第二种也不支持第三种。因此,它们不能从函数返回或传递到其他地方。这是最适合RAII的目的,其中智能指针保持在本地,只是创建,以便在对象超出作用域后释放对象。

Share of ownership can be implemented by having a copy constructor. This naturally copies a smart pointer and both the copy and the original will reference the same object. Transfer of ownership cannot really be implemented in C++ currently, because there are no means to transfer something from one object to another supported by the language: If you try to return an object from a function, what is happening is that the object is copied. So a smart pointer that implements transfer of ownership has to use the copy constructor to implement that transfer of ownership. However, this in turn breaks its usage in containers, because requirements state a certain behavior of the copy constructor of elements of containers which is incompatible with this so-called "moving constructor" behavior of these smart pointers.

c++ 1x通过引入所谓的“移动构造函数”和“移动赋值操作符”,为所有权转移提供了本地支持。它还附带了一个名为unique_ptr的所有权转移智能指针。

智能指针分类

Scoped_ptr是一个既不可转让也不可共享的智能指针。它只在本地需要分配内存时可用,但要确保在超出作用域时再次释放它。但是如果您希望这样做,它仍然可以与另一个scoped_ptr交换。

Shared_ptr是一个共享所有权的智能指针(上面的第三种)。它被引用计数,所以它可以看到它的最后一个副本何时超出作用域,然后它释放被管理的对象。

weak_ptr is a non-owning smart pointer. It is used to reference a managed object (managed by a shared_ptr) without adding a reference count. Normally, you would need to get the raw pointer out of the shared_ptr and copy that around. But that would not be safe, as you would not have a way to check when the object was actually deleted. So, weak_ptr provides means by referencing an object managed by shared_ptr. If you need to access the object, you can lock the management of it (to avoid that in another thread a shared_ptr frees it while you use the object) and then use it. If the weak_ptr points to an object already deleted, it will notice you by throwing an exception. Using weak_ptr is most beneficial when you have a cyclic reference: Reference counting cannot easily cope with such a situation.

intrusive_ptr is like a shared_ptr but it does not keep the reference count in a shared_ptr but leaves incrementing/decrementing the count to some helper functions that need to be defined by the object that is managed. This has the advantage that an already referenced object (which has a reference count incremented by an external reference counting mechanism) can be stuffed into an intrusive_ptr - because the reference count is not anymore internal to the smart pointer, but the smart pointer uses an existing reference counting mechanism.

Unique_ptr是一个所有权转移指针。你不能复制它,但是你可以通过使用c++ 1x的move构造函数来移动它:

unique_ptr<type> p(new type);
unique_ptr<type> q(p); // not legal!
unique_ptr<type> r(move(p)); // legal. p is now empty, but r owns the object
unique_ptr<type> s(function_returning_a_unique_ptr()); // legal!

This is the semantic that std::auto_ptr obeys, but because of missing native support for moving, it fails to provide them without pitfalls. unique_ptr will automatically steal resources from a temporary other unique_ptr which is one of the key features of move semantics. auto_ptr will be deprecated in the next C++ Standard release in favor of unique_ptr. C++1x will also allow stuffing objects that are only movable but not copyable into containers. So you can stuff unique_ptr's into a vector for example. I'll stop here and reference you to a fine article about this if you want to read more about this.