Boost 中的smart pointer

   最近在开发中用到了Boost 中的shared_ptr<> 下面就是一些学习的心得:

  1 what is smart pointer

    smart pointer 就是封装了普通pointer的一个数据结构,能够实现普通pointer所不能实现的功能,比如自动分配内存、自动释放内存,自动进行异常处理等。

  2 why I need them?

    在我们开发中,C++中的内存管理、异常处理是我们最头疼的事情, 有了这个smart pointer我们就可以省去许多事情。 

void foo ()

{
MyClass * p(new MyClass );
p->DoSomething ();
delete p;
}
Let's take another look at this simple example:

void
 foo
()
{
MyClass * p(new MyClass );
p->DoSomething ();
delete p;
}

What happens if DoSomething() throws an exception? All the lines after it will not get executed and p will never get deleted! If we're lucky, this leads only to memory leaks. However, MyClass may free some other resources in its destructor (file handles, threads, transactions, COM references, mutexes) and so not calling it my cause severe resource locks.

If we use a smart pointer, however, p will be cleaned up whenever it gets out of scope, whether it was during the normal path of execution or during the stack unwinding caused by throwing an exception.

But isn't it possible to write exception safe code with regular pointers? Sure, but it is so painful that I doubt anyone actually does this when there is an alternative. Here is what you would do in this simple case:

void
 foo
()
{
MyClass * p;
try {
p = new MyClass ;
p->DoSomething ();
delete p;
}
catch (...) {
delete p;
throw ;
}
}

Now imagine what would happen if we had some if's and for's in there...

3   我可以在代码中显示的delete 他们吗

    不能。因为所有的smart pointer的析构函数是private的,不能够显示的delete。只能通过reset函数来释放。如果shared_ptr的use count 不是0,那么调用reset只是会将该指针NULL, 而不会delete 内存。

  shared_ptr<obj> a(new obj);

  shared_ptr<obj>  b;

  b =a ;

  a.reset(); //a=NULL了,但是new obj的内存并没有释放。

  b.reset(); //b=NULL了,new obj也释放了

 

 

4 Boost中的都有哪些类型,区别是什么

 

Basic properties of smart pointers

It's easy when you have properties that you can assign each smart pointer. There are two important properties.

  • transfer of ownership
  • share of ownership

The first means that only one smart pointer ever can point to the same object at the same time. If the smart pointer is to be returned from functions, the ownership is transferred to the returned smart pointer, for example.

The second means that multiple smart pointers can point to the same object the same time. This is what applies to a raw pointer to: Two pointers can point to the same object. Thus, this is what one would use by default, if there is no strict need for another kind of smart pointer.

Some smart pointer support neither the first nor the second. They can therefor not be returned from functions or passed somewhere else. Most suitable for RAII purposes where the smart pointer is kept local and is just created so it free's an object after it goes out of scope.

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 can not be really implemented in C++ currently, because there is 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 provides native support for transfer-of-ownership by introducing so-called "move constructors" and "move assignment operators". It also comes with such a transfer-of-ownership smart pointer called unique_ptr .

Categorizing smart pointers

scoped_ptr is a smart pointer that is neither transferable nor sharable. It's just usable if you locally need to allocate memory, but be sure it's freed again when it goes out of scope. But it can still be swapped with another scoped_ptr, if you wish to do so.

shared_ptr is a smart pointer that shares ownership (second kind above). It is reference counted so it can see when the last copy of it goes out of scope and then it frees the object managed.

weak_ptr is not really a smart pointer itself, but it is used to reference a manged 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 a mean 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. Often this will also provide a speed enhancement, because the reference count can be stored in the managed object itself (thus the name intrusive) which provides better cache locality.

unique_ptr is a transfer of ownership pointer. You cannot copy it, but you can move it by using C++1x's move constructors:

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_uique_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.

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值