c++11中的智能指针
2015-11-29 14:41
573 查看
下面是《深入理解c++11》中的截图
在头文件<memory>中,使用std::命名空间
以下是自己的实现,有更详细的注释
在头文件<memory>中,使用std::命名空间
以下是自己的实现,有更详细的注释
#include <stdlib.h> #include <iostream> #include <sstream> #include <string> #include <memory> class Human { public: Human() : mNum(nullptr) { mNum = new int(123); printf("Human 构造\n"); } Human(const Human& _h) { mNum = new int(*_h.mNum); printf("Human 拷贝构造\n"); } Human(Human && _h) { mNum = _h.mNum; // _h.mNum = nullptr; //必须将被偷者的指针置空,不然临时对象析构时会释放内存 printf("Human 移动构造\n"); } virtual ~Human() { printf("Human 析构\n"); if (mNum) delete mNum; } void show(){ if(mNum) printf("--- num:%d\n", *mNum); } private: int* mNum; }; void testSmartPoint1() { std::unique_ptr<Human> up1(new Human); //std::unique_ptr<Human> h2 = h1; //编译失败, up1->show(); std::unique_ptr<Human> up3 = std::move(up1); //将h1对new Human的所有权交给h3,h1置空empty up3->show(); //对象会随着最后拥有对象的唯一指针的生命周期的结束而结束 //h1->show();//运行时崩溃,h1已交出对象所有权,现在为empty状态 up3.reset();//已显式释放对象内存 //h3->show();//运行时崩溃,已显式释放对象内存,现在为empty状态 system("pause"); } void testSmartPoint2() { //如果std::shared_ptr<Human> sp1为empty状态,则不会进入这样的判断if(sp1) //void reset() _NOEXCEPT //{ // release resource and convert to empty shared_ptr object // shared_ptr().swap(*this); //} //use_count() {return (_Rep ? _Rep->_Use_count() : 0);} /* reset函数 是用初始化一个shared_ptr()对象(里面的_Rep和_Ptr初始化都是nullptr), 然后调用swap(T&a),实现将a的_Rep和_Ptr都置为nullptr 调用过一次后,之后所以无论调多少次reset,都是做无用功 use_count函数 判断_Rep是否nullptr,不为nullptr则返回对象的引用次数 */ std::shared_ptr<Human> sp1(new Human()); std::shared_ptr<Human> sp2 = sp1; std::shared_ptr<Human> sp3 = sp1; printf("--- ref count:%ld\n", sp2.use_count());//3 sp1.reset(); //显式减少引用,_Rep和_Ptr都置为nullptr,sp1为empty状态 sp1.reset(); //做无用功 sp1.reset(); //做无用功 printf("--- sp1 ref count:%ld\n", sp1.use_count()); //0 //sp1->show(); //此时sp1为empty状态,不可以在使用sp1->show() printf("--- sp2 ref count:%ld\n", sp2.use_count()); //2 //因为此时sp3和sp2还保持这对对象的引用,所以对象还未被释放 printf("--- sp3 ref count:%ld\n", sp3.use_count()); //2 sp2.reset();//减少引用后,_Rep和_Ptr都置为nullptr,sp2为empty状态 printf("--- sp2 ref count:%ld\n", sp2.use_count()); //0 printf("--- sp3 ref count:%ld\n", sp3.use_count()); //1 //因为此时sp3还保持这对对象的引用,所以对象还未被释放 sp3.reset();//减少引用后,_Rep和_Ptr都置为nullptr,sp3为empty状态 //此时已无shared_ptr对sp3保持引用,对象被释放 printf("--- sp3 ref count:%ld\n", sp3.use_count()); //0 system("pause"); } /* Human 构造 --- ref count:3 --- sp1 ref count:0 --- sp2 ref count:2 --- sp3 ref count:2 --- sp2 ref count:0 --- sp3 ref count:1 Human 析构 --- sp3 ref count:0 请按任意键继续. . . */ void testSmartPoint3() { std::shared_ptr<Human> sp1(new Human()); std::shared_ptr<Human> sp2 = sp1; std::weak_ptr<Human> wp = sp1; //不会影响引用计数 printf("--- ref count:%ld\n", sp2.use_count());//2 sp2.reset(); printf("--- sp1 count:%ld\n", sp1.use_count());//1 std::shared_ptr<Human> sp4 = wp.lock(); //如果此时还有对对象保持引用,这行代码结束后sp4也将会保持引用,引用计数+1 if (sp4) printf("--- sp4 ref count:%ld\n", sp4.use_count());//2 sp1.reset(); printf("--- wp ref count:%ld\n", wp.use_count());//1 if (sp4) sp4.reset(); //这行代码后,将无std::shared_ptr对对象保持引用,对象将析构 printf("--- wp ref count:%ld\n", wp.use_count());//0 std::shared_ptr<Human> sp5 = wp.lock(); //如果此时没有对对象保持引用,则sp5是empty状态 if (sp5) printf("--- sp5 ref count:%ld\n", sp4.use_count()); } int main() { //testSmartPoint1(); //testSmartPoint2(); testSmartPoint3(); system("pause"); return 0; }
相关文章推荐
- c++模板实现多参数任意传 - 类实现
- effective c++ 笔记之static_cast
- vs2008 dlib编译问题USER_ERROR__missing_dlib_all_source_cpp_file__OR__inconsistent_use_of_DEBUG_or_ENABLE
- 【C++】满二叉树与完全二叉树的区别及判断
- C++引用方式实现两个值的互换
- C++运算符重载
- C++抛出异常与传递参数的区别
- C++抛出异常与传递参数的区别
- C++【线程同步】-临界区同步
- c/c++进制转换
- C++的chrono、ratio和ctime等头文件
- leetcode Search a 2D Matrix
- C语言命名空间
- c语言字符数组与字符串的使用详解
- 读取文本文件,打印到屏幕
- C语言中switch的用法
- 合并两个排序的链表(C++版)
- C++模版完全解析
- C++中的static关键字
- C++标准库Vector & Iterator用法