在
C++
中需要自己来处理内存,稍微处理不当,就会存在非常郁闷的内存泄漏问题
还好,现在
C++
中推出了强大的智能指针,即
smart_ptr
,本文先稍微介绍一下
smart_ptr
,然后具体说说
shared_ptr
和
weak_ptr
,特别是
enable_shared_from_this
和
shared_from_this
除了标准库中的
auto_ptr
之外
在
boost
或者
tr1
中的
smart_ptr
主要是有下面几种
-
scoped_ptr
-
scoped_array
-
shared_ptr
-
shared_array
-
intrusive_ptr
-
weak_ptr
这些里面最难理解的是综合应用了
weak_ptr
和
shared_ptr
的
enable_shared_from_this
类,在该类中定了成员函数
shared_from_this()
,返回
shared_ptr
。这个函数仅在
shared_ptr
的构造函数被调用之后才能使用。原因是
enable_shared_from_this::weak_ptr
并不在构造函数中设置(此处的构造函数指的是类型
T
的构造函数),而是在
shared_ptr
的构造函数中设置(此处的构造函数指的是类型
shared_ptr
的构造函数)。
在下面的代码中:
- #include
-
- #include
-
-
-
- #include
-
- #include
-
- #include
-
-
-
- using namespace std;
-
-
-
- struct Ansible
-
- : public boost::enable_shared_from_this
-
- {
-
- boost::shared_ptr get_shared()
-
- {
-
- boost::shared_ptr r(this);
-
-
-
- return r;
-
- }
-
-
-
- ~Ansible()
-
- {
-
- cout<<"Destructor"<
-
- }
-
- };
-
-
-
- int main(int argc,char* argv[])
-
- {
-
- boost::shared_ptr a(new Ansible);
-
- Ansible& r = *a;
-
-
-
- boost::shared_ptr b = r.shared_from_this();
-
-
-
- cout<<"Reference Number "<" "<
-
-
-
- return 0;
-
- }
#include
#include
#include
#include
#include
using namespace std;
struct Ansible
: public boost::enable_shared_from_this
{
boost::shared_ptr get_shared()
{
boost::shared_ptr r(this);
return r;
}
~Ansible()
{
cout<<"Destructor"< a(new Ansible);
Ansible& r = *a;
//boost::shared_ptr b = r.get_shared();
boost::shared_ptr b = r.shared_from_this();
cout<<"Reference Number "<
若不使用
shared_from_this()
成员函数,则会输出
a
和
b
的
use_count()
都为
1
,然后调用
2
次类型
Ansible
的析构函数,若添加了该成员函数,在
a
和
b
的
use_count()
输出为
2
,只是调用一次
Ansible
的析构函数。原因是
enable_shared_from_this
里面在
shared_ptr
的时候构造了一个
weak_ptr
类,而
weak_ptr
只是监视,不增加引用计数
(下面是转载:
http://huyuguang1976.spaces.live.com/blog/cns!2A9E272E3C33AFF1!185.entry
)
所以如下代码是错误的:
class D:public boost::enable_shared_from_this
{
public:
D()
{
boost::shared_ptr p=shared_from_this();
}
};
原因很简单,在
D
的构造函数中虽然可以保证
enable_shared_from_this
的构造函数已经被调用,但正如前面所说,
weak_ptr
还没有设置。
如下代码也是错误的:
class D:public boost::enable_shared_from_this
{
public:
void func()
{
boost::shared_ptr p=shared_from_this();
}
};
void main()
{
D d;
d.func();
}
错误原因同上。
如下代码是正确的:
void main()
{
boost::shared_ptr
d(new D);
d->func();
}
这里
boost::shared_ptr d(new D)
实际上执行了
3
个动作:首先调用
enable_shared_from_this
的构造函数;其次调用
D
的构造函数;最后调用
shared_ptr
的构造函数。是第
3
个动作设置了
enable_shared_from_this
的
weak_ptr
,而不是第
1
个动作。这个地方是很违背
c++
常理和逻辑的,必须小心。
结论是,不要在构造函数中使用
shared_from_this
;其次,如果要使用
shared_ptr
,则应该在所有地方均使用,不能使用
D d
这种方式,也决不要传递裸指针。