一、智能指针
1、智能指针的意义
(1)、现代c++开发库中最重要的类模板之一
(2)、c++中自动内存管理的重要手段
(3)、能够很大程度上避开内存相关的问题
2、STL中的只能指针auto_ptr
(1)、生命周期结束时,销毁指向的内存空间
(2)、不能指向堆数组(否则发生内存泄漏),只能指向堆对象(变量)
(3)、一片堆空间只属于一个内存指针对象(防止多次释放)
(4)、多个只能指针对象不能指向同一片堆空间
#include#include #include using namespace std;class Test{ string m_name;public: Test(const char* name) { cout << "Hello, " << name << "." << endl; m_name = name; } void print() { cout << "I'm " << m_name << "." << endl; } ~Test() { cout << "Goodbye, " << m_name << "." << endl; }};int main(){ auto_ptr pt(new Test("D.T.Software")); cout << "pt = " << pt.get() << endl;//打印指针的地址 pt->print(); cout << endl; auto_ptr pt1(pt);//这句之后发生了所有权的转移,即pt1指向了原来pt指向的内存,而pt=NULL cout << "pt = " << pt.get() << endl;//0 cout << "pt1 = " << pt1.get() << endl;//与之前的pt指针一样 pt1->print(); return 0;}
3、STL中的其它智能指针
(1)、shared_ptr:带有引用计数机制,支持多个指针对象指向同一片内存
(2)、weak_ptr:配合shared_ptr而引入的一种智能指针
(3)、unique_ptr:一个指针对象指向一片内存,不能拷贝构造和赋值
二、Qt中的智能指针
1、QPoiter
(1)、当其指向的对象被销毁时,它会被自动置空(避免野指针)
(2)、析构时不会自动销毁所指向的对象(特别注意)
2、QSharedPoiter
(1)、引用计数型智能指针
(2)、可以被自动拷贝和赋值
(3)、当引用计数为0时才销毁指向的对象
3、Qt中的其它智能指针
#include#include #include class Test : public QObject{ QString m_name;public: Test(const char* name) { m_name = name; qDebug() << "Hello, " << m_name << "."; } void print() { qDebug() << "I'm " << m_name <<"."; } ~Test() { qDebug() << "Good bye, " << m_name <<"."; }};int main(){ QPointer pt(new Test("SantaClaus"));//pt= new Test("SantaClaus"); QPointer pt1(pt); //所有权不会转让!与pt指向同一个堆空间 QPointer pt2(pt); //所有权不会转让!与pt指向同一个堆空间 pt->print(); pt1->print(); pt2->print(); delete pt; //删除对象时,pt、pt1和pt2会同时被置空 //注意,pt本身是一个局部对象(而不是指针),但因QPointer 实现了operator Test*()这个类型转换函数(见第42课) //当delete pt时,由于delete要求后面跟一个指针,所以将隐式的把pt对象转为Test*指针类型。因此,删除的是pt //所指的对象,而不是pt本身。 qDebug() << "pt = " << pt; qDebug() << "pt1 = " << pt1; qDebug() << "pt2 = " << pt2; qDebug() << endl; //带有引用计数 QSharedPointer spt(new Test("Demo")); QSharedPointer spt1(spt); QSharedPointer spt2(spt); spt->print(); spt1->print(); spt2->print(); return 0;}/*输出结果Hello, "SantaClaus" .I'm "SantaClaus" .I'm "SantaClaus" .I'm "SantaClaus" .Good bye, "SantaClaus" .pt = QObject(0x0)pt1 = QObject(0x0)pt2 = QObject(0x0)Hello, "Demo" .I'm "Demo" .I'm "Demo" .I'm "Demo" .Good bye, "Demo" .*/
三、创建智能指针类模板
//SmartPoiter.h
#ifndef _SMARTPOITER_H_#define _SMARTPOITER_H_templateclass SmartPoiter{private: T* mp;public: SmartPoiter(T* p = NULL); SmartPoiter(const SmartPoiter & obj); SmartPoiter & operator = (const SmartPoiter & obj); T* operator -> (); T& operator * (); T* get(); ~SmartPoiter();};template SmartPoiter ::SmartPoiter(T* p){ mp =p;} template SmartPoiter ::SmartPoiter(const SmartPoiter & obj){ mp = obj.mp; const_cast &>(obj).mp = NULL;//转让所有权}template SmartPoiter & SmartPoiter ::operator = (const SmartPoiter & obj)//重载赋值操作符的四个注意点{ if(this != &obj) { delete mp; mp = obj.mp; const_cast &>(obj).mp = NULL;//转让所有权 } return *this;}template T* SmartPoiter ::operator -> () { return mp; } template T& SmartPoiter ::operator * () { return *mp; } template T* SmartPoiter ::get() { return mp; } template SmartPoiter ::~SmartPoiter(){ delete mp;}#endif
//main.cpp
#include#include"SmartPoiter.h"using namespace std;class Test{ string m_name;public: Test() { m_name = "SantaClaus"; cout <<"Hello, " << m_name << "." << endl; } Test(const char* name) { m_name = name; cout <<"Hello, " << m_name << "." << endl; } void print() { cout << "I'm " << m_name << "." << endl; } ~Test() { cout << "Good bye, " << m_name << "." << endl; }};int main(){ SmartPoiter pt(new Test("D.T.Software"));//本质上还是个对象 cout << pt.get()<< endl; SmartPoiter pt1(pt);//验证拷贝构造函数的所有权转让 cout << pt.get()<< endl;//0 cout << pt1.get()<< endl; SmartPoiter pt2; pt2 = pt1;//验证赋值操作符的所有权转让 cout << pt1.get()<< endl;//0 cout << pt2.get()<< endl; return 0;}
四、小结
(1)、智能指针是C++中自动内存管理的主要手段
(2)、智能指针在各种平台上都有不同的表现形式
(3)、智能指针能够尽可能的避开内存相关的问题
(4)、STL和Qt中提供了对智能指针的支持