#include<iostream> using namespace std; //智能指针: //1.用起来像指针(不是指针) //2.会自己对资源进行释放 class CStudent { public: CStudent() {
} void test() { cout << "CStudent" << endl; } private: char* m_pszBuf; int m_nSex; }; //为了对象创建时刻,由他自己决定什么时候释放,程序员不用考虑 //我们可以创建一个类,利用该类的构造和析构(进出作用域自动被编译器调用)的机制。 //来解决资源自动释放问题
//智能指针雏形 需要管理资源 class CSmartPtr { public: //一定要是一个堆对象 CSmartPtr(CStudent *obj) { m_pobj = obj; } ~CSmartPtr() { if (m_pobj != nullptr) { delete m_pobj; } }
CSmartPtr& operator=(CSmartPtr&sp) { if (m_pobj != nullptr) { delete m_pobj; } m_pobj = sp.m_pobj; sp.m_pobj = nullptr; return m_pobj; } CSmartPtr(CSmartPtr&) = delete; //因为用起来不像指针,所以我们需要想办法让其对象用起来像是一个指针。 //像一个指针的写法 CStudent* operator->() { return this->m_pobj; } CStudent& operator*() { return *this->m_pobj; } operator bool() { return this->m_pobj != nullptr; } private: CStudent* m_pobj;//将资源放入智能指针类中,管理起来 }; int main() { CStudent* stu = new CStudent(); /*CSmartPtr* ptr = new CStudent(stu);*/ //这里可以完成资源的自动释放R CSmartPtr sp(new CStudent()); CSmartPtr sp3(new CStudent()); sp3 = sp;//一般不允许这样子,有可能同一个空间被释放两次,这个时候就需要自定义下=运算符 //但是赋值完之后,sp的内容就没有了 //sp->test();//不能再这么使用了 CSmartPtr sp2 = sp; //1.不允许=号运算符重载 //2.使用拷贝构造移动的语法,auto_ptr 98的原型 //3.结合前面的引用计数以及写时拷贝。新的智能指针的写法 sp->test(); (*sp).test(); if (sp) { } //但是用起来不像是一个指针, /*CStudent* stu = new CStudent(); 正常的申请释放 if (stu != nullptr) { delete stu; stu = nullptr; }*/ return 0; }