智能指针的使用和简单实现
Agenda <ul><li>什么是智能指针? </li></ul><ul><li>智能指针间的特性区别? </li></ul><ul><li>如何去设计智能指针? </li></ul>
什么是智能指针 <ul><li>何物:类的对象 </li></ul><ul><li>方法:提供  ->  和  *  操作符来模拟一般指针的行为 </li></ul><ul><li>好处:拥有权( Owenership )的管理 </li></ul>
提供  ->  和  * template <typename T> class SmartPtr { public: explicit SmartPtr(T* pointee) {this->pointee_ = pointee;}; ~Sm...
简单的例子 :Bad Code <ul><li>int main(int argc, char** argv) { </li></ul><ul><li>string* my_name = new string(&quot;wuliang&quo...
现实代码 <ul><li>string* my_name = new string(&quot;wuliang&quot;); </li></ul><ul><li>if ( 条件一 ){delete my_name; return;} </li...
如果是智能指针 <ul><li>int main(int argc, char** argv) { </li></ul><ul><li>auto_ptr<string> my_name(newstring(&quot;wuliang&quot;...
智能指针提供的一般方法 <ul><li>get :得到具体的指针地址 </li></ul><ul><li>* :间接引用对象 </li></ul><ul><li>-> :间接引用对象的成员 </li></ul><ul><li>= : auto_...
shared_ptr 还定义了其他一些 <ul><li>use_count  返回计数器值 </li></ul><ul><li>swap  交换两个智能指针中的内容 </li></ul>
目前常见的智能指针 <ul><li>std::auto_ptr </li></ul><ul><li>boost::shared_ptr 等 </li></ul><ul><li>loki 中的 SmartPtr </li></ul>
它们之间的区别 std::auto_ptr 销毁式、不能应用于 STL 容器和数组 scoped_ptr const std::auto_ptr scoped_array const std::auto_ptr for array shared...
为什么需要 weak_ptr (强引用) class Children { public: boost::shared_ptr<Parent> his_parent; }; boost::shared_ptr<Parent> father(ne...
使用 weak_ptr <ul><li>class Children { </li></ul><ul><li>public: </li></ul><ul><li>boost::weak_ptr<Parent> his_parent; </li>...
如何设计智能指针 <ul><li>Storage Policy </li></ul><ul><li>Ownership policy </li></ul><ul><li>Conversion policy </li></ul><ul><li>C...
Storage Policy <ul><li>深层拷贝 </li></ul><ul><li>引用计数 </li></ul><ul><li>引用链接 </li></ul><ul><li>摧毁式 </li></ul>
深层拷贝
引用计数
引用计数
引用计数
引用链接
Conversion policy <ul><li>这段代码可以编译通过吗? </li></ul><ul><li>void Fun(Something* p); </li></ul><ul><li>... </li></ul><ul><li>S...
由设计者决定 <ul><li>template<typename T> </li></ul><ul><li>class SmartPtr { </li></ul><ul><li>public: </li></ul><ul><li>operato...
Checking policy <ul><li>初始化检查:不应该接受 NULL …… </li></ul><ul><li>使用前检查:在调用 * 或者 -> 时,至少不应该返回 NULL …… </li></ul><ul><li>必要的错误报...
一切都组合起来 #include <cstdlib> #include <iostream> #include <string> #include <loki/SmartPtr.h> using namespace std; typedef L...
参考资料 <ul><li>C++ 标准程序库的 4.2 章对 std::auto_ptr 的介绍 </li></ul><ul><li>boost 文档中关于 shared_ptr 等的使用和 API 介绍 </li></ul><ul><li>C...
Q/A
Upcoming SlideShare
Loading in …5
×

Smart pointer

1,206 views
1,137 views

Published on

之前分享的智能指针

Published in: Education, Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,206
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
14
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • 当然,拥有权的管理其实有很多种方式,比如: Std::auto_ptr 的转移后销毁 Boost::shared_ptr 的引用计数 其实你完成可以设计一个智能指针,让它不主动地释放它们所指的对象,而是去做一些别的什么事
  • 这里有
  • 强引用就是被引用的对象活着的话,这个引用也存在。也就是说,当至少存在一个强引用时,那么这个对象就不会被释放,典型的就是 shared_ptr 相对强引用,弱引用只是一个观察者,它不会接受所有权,也不会增加计数器
  • 当然,还有一些其他的细节: ( 1 )最好不要重载 address-of 操作符 ( 2 )相等性测试和不等性测试 ( 3 )比较 ( 4 )对 Arrary 的支持 ……
  • 空间上的浪费
  • 效率上的浪费
  • Smart pointer

    1. 1. 智能指针的使用和简单实现
    2. 2. Agenda <ul><li>什么是智能指针? </li></ul><ul><li>智能指针间的特性区别? </li></ul><ul><li>如何去设计智能指针? </li></ul>
    3. 3. 什么是智能指针 <ul><li>何物:类的对象 </li></ul><ul><li>方法:提供 -> 和 * 操作符来模拟一般指针的行为 </li></ul><ul><li>好处:拥有权( Owenership )的管理 </li></ul>
    4. 4. 提供 -> 和 * template <typename T> class SmartPtr { public: explicit SmartPtr(T* pointee) {this->pointee_ = pointee;}; ~SmartPtr(); SmartPtr& operator =(const SmartPtr& other); T& operator *() const {return *pointee_;}; T* operator ->() const {return pointee_;}; private: T* pointee_; }; class Foo { public: void get(); }; SmartPtr<Foo> foo(new Foo); foo->get(); (*foo).get();
    5. 5. 简单的例子 :Bad Code <ul><li>int main(int argc, char** argv) { </li></ul><ul><li>string* my_name = new string(&quot;wuliang&quot;); </li></ul><ul><li>cout << *my_name << endl; </li></ul><ul><li>} </li></ul>
    6. 6. 现实代码 <ul><li>string* my_name = new string(&quot;wuliang&quot;); </li></ul><ul><li>if ( 条件一 ){delete my_name; return;} </li></ul><ul><li>else if ( 条件 2) {delete my_name; return;} </li></ul><ul><li>delete my_name; </li></ul>
    7. 7. 如果是智能指针 <ul><li>int main(int argc, char** argv) { </li></ul><ul><li>auto_ptr<string> my_name(newstring(&quot;wuliang&quot;)); </li></ul><ul><li>if ( 条件一 ){return;} </li></ul><ul><li>else if ( 条件 2) {return;} </li></ul><ul><li>} </li></ul>
    8. 8. 智能指针提供的一般方法 <ul><li>get :得到具体的指针地址 </li></ul><ul><li>* :间接引用对象 </li></ul><ul><li>-> :间接引用对象的成员 </li></ul><ul><li>= : auto_ptr 是 relese+copy , shared_ptr 只是 copy </li></ul><ul><li>release: 释放指针 </li></ul><ul><li>reset: 释放指针并且设置新值 </li></ul>
    9. 9. shared_ptr 还定义了其他一些 <ul><li>use_count 返回计数器值 </li></ul><ul><li>swap 交换两个智能指针中的内容 </li></ul>
    10. 10. 目前常见的智能指针 <ul><li>std::auto_ptr </li></ul><ul><li>boost::shared_ptr 等 </li></ul><ul><li>loki 中的 SmartPtr </li></ul>
    11. 11. 它们之间的区别 std::auto_ptr 销毁式、不能应用于 STL 容器和数组 scoped_ptr const std::auto_ptr scoped_array const std::auto_ptr for array shared_ptr 引用计数实现多个指针共享对象的所有权 shared_array weak_ptr intrusive_ptr ?
    12. 12. 为什么需要 weak_ptr (强引用) class Children { public: boost::shared_ptr<Parent> his_parent; }; boost::shared_ptr<Parent> father(new Parent()); boost::shared_ptr<Children> son(new Children()); // memory leak will be happended in here father->his_children = son; son->his_parent = father;
    13. 13. 使用 weak_ptr <ul><li>class Children { </li></ul><ul><li>public: </li></ul><ul><li>boost::weak_ptr<Parent> his_parent; </li></ul><ul><li>}; </li></ul>
    14. 14. 如何设计智能指针 <ul><li>Storage Policy </li></ul><ul><li>Ownership policy </li></ul><ul><li>Conversion policy </li></ul><ul><li>Checking policy </li></ul>
    15. 15. Storage Policy <ul><li>深层拷贝 </li></ul><ul><li>引用计数 </li></ul><ul><li>引用链接 </li></ul><ul><li>摧毁式 </li></ul>
    16. 16. 深层拷贝
    17. 17. 引用计数
    18. 18. 引用计数
    19. 19. 引用计数
    20. 20. 引用链接
    21. 21. Conversion policy <ul><li>这段代码可以编译通过吗? </li></ul><ul><li>void Fun(Something* p); </li></ul><ul><li>... </li></ul><ul><li>SmartPtr<Something> sp(new Something); </li></ul><ul><li>Fun(something); </li></ul>
    22. 22. 由设计者决定 <ul><li>template<typename T> </li></ul><ul><li>class SmartPtr { </li></ul><ul><li>public: </li></ul><ul><li>operator T* () {return pointee_}; </li></ul><ul><li>}; </li></ul>
    23. 23. Checking policy <ul><li>初始化检查:不应该接受 NULL …… </li></ul><ul><li>使用前检查:在调用 * 或者 -> 时,至少不应该返回 NULL …… </li></ul><ul><li>必要的错误报告 </li></ul>
    24. 24. 一切都组合起来 #include <cstdlib> #include <iostream> #include <string> #include <loki/SmartPtr.h> using namespace std; typedef Loki::SmartPtr<string, Loki::RefCounted, Loki::DisallowConversion, Loki::AssertCheck, Loki::DefaultSPStorage> SmartPointer; int main(int argc, char **argv) { SmartPointer myName(new string(&quot;Wu Liang&quot;)); SmartPointer copiedName = myName; cout << *myName << endl; cout << *copiedName << endl; }
    25. 25. 参考资料 <ul><li>C++ 标准程序库的 4.2 章对 std::auto_ptr 的介绍 </li></ul><ul><li>boost 文档中关于 shared_ptr 等的使用和 API 介绍 </li></ul><ul><li>C++ 设计新思维的第 7 章中关于对智能指针实现的介绍 </li></ul>
    26. 26. Q/A

    ×