智能指针

    xiaoxiao2021-04-17  37

    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_ptr unique_ptr<CMyClass> p(new CMyClass(1)); p->test(); //unique_ptr<CMyClass> p1 = p; //无法通过编译 CMyClass cls = *p;//调用CMyClass的复制构造函数,若想禁止调用复制构造函数,将复制构造函数生命诚private cls.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_ptr shared_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; }
    转载请注明原文地址: https://ju.6miu.com/read-674094.html

    最新回复(0)