C++之智能指针初学
参考链接:https://blog.csdn.net/kang_tju/article/details/76515894
https://www.cnblogs.com/TenosDoIt/p/3456704.html
1.auto_ptr:
#include <iostream> #include <memory> using namespace std; class test { public: test(int cvalue) { m_value = cvalue; cout << "creat test" << m_value <<endl; } ~test() { cout << "destory test" << m_value << endl; } void setValue(int value) { m_value = value; } void getValue() { cout << m_value << endl; } private: int m_value; }; void testFunc(auto_ptr<test> obj) { obj->getValue(); } int main() { auto_ptr<test> ptest(new test(1)); auto_ptr<test> ptest2(new test(2)); ptest->setValue(3); ptest->getValue(); ptest2->setValue(4); ptest2->getValue(); ptest = ptest2; //将ptest2的所有权移交给了ptest.此时ptest之前的资源被析构掉了 ptest->getValue(); testFunc(ptest); //cout << ptest->getValue() << endl; //这句话是错误的,应为auto_ptr在函数参数传递的时候,进行了一个复制。 if (ptest2.get() == NULL) cout << "ptest2.get() is NULL" << endl; system("pause"); return 0; }
输出结果:
2.unique_ptr:独享所有权的语义
#include <iostream> #include <memory> #include <vector> using namespace std; class test { public: test(int cvalue) { m_value = cvalue; cout << "creat test" << m_value <<endl; } ~test() { cout << "destory test" << m_value << endl; } void setValue(int value) { m_value = value; } void getValue() { cout << m_value << endl; } private: int m_value; }; void testFunc(auto_ptr<test> obj) { obj->getValue(); } void testFunc(unique_ptr<test> obj) { obj->getValue(); } int main() { //unique_ptr: unique_ptr<test> uni_test(new test(0)); unique_ptr<test> uni_test1(new test(3)); unique_ptr<test> tPtr; //这里没有分配内存,因此是没有构造的; cout << sizeof(uni_test)<<endl; cout << sizeof(tPtr) << endl; uni_test->getValue(); uni_test->setValue(1); uni_test->getValue(); tPtr = move(uni_test); tPtr->setValue(2); tPtr->getValue(); //unique_ptr能够放在vector中 vector<unique_ptr<test>> vec; vec.push_back(move(tPtr)); vec.push_back(move(uni_test1)); for (int i = 0 ; i < vec.size() ; i++) { vec[i]->getValue(); } system("pause"); return 0; }
3.shaerd_ptr基于共享语义实现
#include <iostream> #include <memory> #include <vector> using namespace std; class test { public: test(int cvalue) { m_value = cvalue; cout << "creat test" << m_value <<endl; } ~test() { cout << "destory test" << m_value << endl; } void setValue(int value) { m_value = value; } void getValue() { cout << m_value << endl; } private: int m_value; }; void testFunc(auto_ptr<test> obj) { obj->getValue(); } void testFunc(unique_ptr<test> obj) { obj->getValue(); } int main() { shared_ptr<test> p_test0(new test(3)); p_test0->getValue(); cout << "p_test0.use_count() = " << p_test0.use_count() << endl; shared_ptr<test> p_test1 = p_test0; cout << "p_test0.use_count() = " << p_test0.use_count() << endl; cout << "p_test1.use_count() = " << p_test1.use_count() << endl; shared_ptr<test> p_test2 = make_shared<test>(4); p_test2->getValue(); p_test1 = p_test2; cout << "p_test2.use_count() = " << p_test2.use_count() << endl; cout << "p_test1.use_count() = " << p_test1.use_count() << endl; cout << "p_test0.use_count() = " << p_test0.use_count() << endl; system("pause"); return 0; }
输出结果:
4. weak_ptr
5. 使用智能指针注意:
- 当指针不具有共享语义的时候,使用了shared_ptr。此时使用unique_ptr即可
- 既然shared_ptr是具有共享语义的,那么对于多线程访问的安全性如何保证!
- auto_ptr禁止使用,作为独占语义的智能指针,我们使用unique_ptr即可
- 关于shared_ptr,尽量使用make_shared来进行初始化。
- 智能指针在创建对象时,如果使用裸指针,应该确保裸指针之后都不会再使用。
- 关于shared_ptr,使用get方法获得裸指针是非常危险的行为!禁止!
- 关于shared_ptr,当使用shared_ptr指向动态数组的时候,需要定义自己的deleter.
- 在使用shared_ptr时形成循环引用,使用weak_ptr来解决这个问题。
- 关于unique_ptr,如果使用release方法之后,unique_ptr从销毁指针的责任中解脱出来,此时还需要手动销毁裸指针。
- 关于weak_ptr,使用的时候,必须调用lock方法来判断它的有效性。
智能指针是一种工具,具体来说是一种类型,用来管理动态内存(dynamic memory or heap memory)。当然,你也可以用new和delete来管理,但是后者比较容易出bug。
智能指针的行为类似常规指针,重要的区别它负责自动释放所指向的对象。C++11提供的三种智能指针分别是unique_ptr,shared_ptr和weak_ptr。
区别是,前者实现了独占语义,后两者则实现了共享语义。语义上的具体体现就是是否允许复制和赋值的语义。在底层实现上是否允许多个指针指向同一个对象。
shared_ptr和weak_ptr的区别是,强引用和弱引用的区别。具体表现为是否增加所指向对象的ref count.
青青园中葵,朝露待日晞。
阳春布德泽,万物生光辉。
常恐秋节至,焜黄华叶衰。
百川东到海,何时复西归?
少壮不努力,老大徒伤悲!