智能指针

来源:互联网 发布:51内核单片机 编辑:程序博客网 时间:2021/05/15 18:57
1.auto_ptr
不提倡使用,因为在C++11中已经明确被废弃。
先定义一个类用来做测试:
#include <memory>#include <iostream>using namespace std;class CMyClass{public:CMyClass(int n) : i(n) {cout<<"CMyClass contructor "<<i<<endl;} CMyClass(const CMyClass& other) {cout<<"CMyClass copy contructor"<<endl;  }~CMyClass() {cout<<"CMyClass destructor"<<i<<endl;}void test() {cout<<"test"<<endl;}private:int i;};
测试代码:
//按值传递void func1(auto_ptr<CMyClass> ap){ap->test();}//按const引用传递void func2(const auto_ptr<CMyClass>& ap){ap->test();}//1.auto_ptr只能用于管理从new返回的一个对象,不支持new数组//2.auto_ptr不能初始化为指向非动态内存int main(){{CMyClass* p = new CMyClass(1);auto_ptr<CMyClass> ap1(p);//动态内存的所有权已转移到ap1,动态内存由ap1负责释放//因为auto_ptr对内存的所有权独有,在析构时ap和ap1都试图删除p。//两次删除同一个对象的行为在C++标准中是未定义的,所以应该防止两个auto_ptr拥有同一个对象(编译器不会报错)auto_ptr<CMyClass> ap(p);auto_ptr<CMyClass> ap2(new CMyClass(2));auto_ptr<CMyClass> ap3(ap2);//ap2->test();//运行异常,因为动态内存的所有权已转移到ap3,动态内存由ap3负责释放ap3->test();auto_ptr<CMyClass> ap4(new CMyClass(4));auto_ptr<CMyClass> ap5(new CMyClass(5));//赋值前,由ap5指向的对象被删除,ap4指向的内存的所有权转移到了ap5(通过单步调试该行,可看出ap5指向对象的析构函数被调用)ap5 = ap4;//智能指针作为参数//应谨慎使用智能指针作为参数传递,如果非要使用的话,请传递一个const引用auto_ptr<CMyClass> ap6(new CMyClass(6));auto_ptr<CMyClass> ap7(new CMyClass(7));func1(ap6);//ap6->test();//error,调用func函数后,ap6已经不再拥有任何对象了func2(ap7);ap7->test();//ok//成员函数//1.get()//第一行与第三行相同,都是p1所在的那块内存的地址。第二行是ap8这个类对象本身所在内存的地址CMyClass* p1 = new CMyClass(0);auto_ptr<CMyClass> ap8(p1);cout<<p1<<endl;cout<<&ap8<<endl;cout<<ap8.get()<<endl;//2.reset()//重新设置auto_ptr指向的对象。类似于赋值操作,但赋值操作不允许将一个普通指针直接赋给auto_ptr,而reset()允许auto_ptr<CMyClass> ap9(new CMyClass(9));ap9.reset(new CMyClass(10));ap9.reset(0);//reset(0)可以销毁对象,释放内存//3.release()//返回auto_ptr指向的那个对象的内存地址,并释放对这个对象的所有权//对于上面的ap和ap1同时拥有对p的所有权的问题,可以让其中一个先释放所有权ap.release();cout<<endl;}return 0;}

2.unique_ptr
跟所指对象的内存紧紧的绑定在一起,不和其他的指针共享其指向的内存
3.shared_ptr
可以赋值,允许多个shared_ptr共享一块内存,它采用了引用计数的内存管理方式
4.weak_ptr
是为配合shared_ptr而引入的一种智能指针来协助shared_ptr工作
template <class T>void IsPtrValid(weak_ptr<T>& wp) {shared_ptr<T> sp = wp.lock();if (sp != nullptr) {cout << "shared_ptr is good" << endl;}else{cout << "shared_ptr is null" << endl;}}int main(){//2.unique_ptr跟所指对象的内存紧紧的绑定在一起,不和其他的指针共享其指向的内存//也就是说unique_ptr不能赋值给别的unique_ptrunique_ptr<CMyClass> p(new CMyClass(1));p->test();//unique_ptr<CMyClass> p1 = p;//无法通过编译CMyClass cls = *p;//调用CMyClass的复制构造函数,若想禁止调用复制构造函数,将复制构造函数生命诚privatecls.test();p.reset();//释放指针拥有的内存呢//3.shared_ptr可以赋值,允许多个shared_ptr共享一块内存,它采用了引用计数的内存管理方式,//因此当它放弃了所有权时并不会释放内存,不会影响其他引用这块内存的指针,只有当引用计数变为0时才会释放内存。shared_ptr<CMyClass> sp(new CMyClass(2));shared_ptr<CMyClass> spcopy = sp;spcopy.reset();//减少引用计数,当引用计数为0时释放拥有的内存sp.reset();
//shared_ptr作为类的成员变量的使用例子如下//在CMyClass中声明:shared_ptr<CMyClass> m_sp;//在CMyClass的构造函数中初始化:m_sp.reset();//在使用时实例化:m_sp.reset(new CMyClass());//在不再使用时释放:m_sp.reset();//4.weak_ptr是为配合shared_ptr而引入的一种智能指针来协助shared_ptr工作//weak_ptr可以指向shared_ptr指向的内存,但不拥有该内存,当调用lock时可以返回指向内存的shared_ptrshared_ptr<CMyClass> sp1(new CMyClass(3));weak_ptr<CMyClass> wp = sp1;IsPtrValid(wp);//输出“shared_ptr is good”sp1.reset();IsPtrValid(wp);//输出“shared_ptr is null”return 0;}

0 0