一、智能指针
1、智能指针的意义
(1)、现代c++开发库中最重要的类模板之一
(2)、c++中自动内存管理的重要手段
(3)、能够很大程度上避开内存相关的问题
2、STL中的只能指针auto_ptr
(1)、生命周期结束时,销毁指向的内存空间
(2)、不能指向堆数组(否则发生内存泄漏),只能指向堆对象(变量)
(3)、一片堆空间只属于一个内存指针对象(防止多次释放)
(4)、多个只能指针对象不能指向同一片堆空间
#include <iostream> #include <string> #include <memory> 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<Test> pt(new Test("D.T.Software")); cout << "pt = " << pt.get() << endl;//打印指针的地址 pt->print(); cout << endl; auto_ptr<Test> 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<QPointer> #include <QSharedPointer> #include <qDebug> 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<Test> pt(new Test("SantaClaus"));//pt= new Test("SantaClaus"); QPointer<Test> pt1(pt); //所有权不会转让!与pt指向同一个堆空间 QPointer<Test> pt2(pt); //所有权不会转让!与pt指向同一个堆空间 pt->print(); pt1->print(); pt2->print(); delete pt; //删除对象时,pt、pt1和pt2会同时被置空 //注意,pt本身是一个局部对象(而不是指针),但因QPointer<Test>实现了operator Test*()这个类型转换函数(见第42课) //当delete pt时,由于delete要求后面跟一个指针,所以将隐式的把pt对象转为Test*指针类型。因此,删除的是pt //所指的对象,而不是pt本身。 qDebug() << "pt = " << pt; qDebug() << "pt1 = " << pt1; qDebug() << "pt2 = " << pt2; qDebug() << endl; //带有引用计数 QSharedPointer<Test> spt(new Test("Demo")); QSharedPointer<Test> spt1(spt); QSharedPointer<Test> 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_ template <typename T> class SmartPoiter { private: T* mp; public: SmartPoiter(T* p = NULL); SmartPoiter(const SmartPoiter<T>& obj); SmartPoiter<T>& operator = (const SmartPoiter<T>& obj); T* operator -> (); T& operator * (); T* get(); ~SmartPoiter(); }; template <typename T> SmartPoiter<T>::SmartPoiter(T* p) { mp =p; } template <typename T> SmartPoiter<T>::SmartPoiter(const SmartPoiter<T>& obj) { mp = obj.mp; const_cast<SmartPoiter<T>&>(obj).mp = NULL;//转让所有权 } template <typename T> SmartPoiter<T>& SmartPoiter<T>::operator = (const SmartPoiter<T>& obj)//重载赋值操作符的四个注意点 { if(this != &obj) { delete mp; mp = obj.mp; const_cast<SmartPoiter<T>&>(obj).mp = NULL;//转让所有权 } return *this; } template <typename T> T* SmartPoiter<T>::operator -> () { return mp; } template <typename T> T& SmartPoiter<T>::operator * () { return *mp; } template <typename T> T* SmartPoiter<T>::get() { return mp; } template <typename T> SmartPoiter<T>::~SmartPoiter() { delete mp; } #endif
//main.cpp
#include<iostream> #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<Test> pt(new Test("D.T.Software"));//本质上还是个对象 cout << pt.get()<< endl; SmartPoiter<Test> pt1(pt);//验证拷贝构造函数的所有权转让 cout << pt.get()<< endl;//0 cout << pt1.get()<< endl; SmartPoiter<Test> pt2; pt2 = pt1;//验证赋值操作符的所有权转让 cout << pt1.get()<< endl;//0 cout << pt2.get()<< endl; return 0; }
四、小结
(1)、智能指针是C++中自动内存管理的主要手段
(2)、智能指针在各种平台上都有不同的表现形式
(3)、智能指针能够尽可能的避开内存相关的问题
(4)、STL和Qt中提供了对智能指针的支持
来源:https://www.cnblogs.com/gui-lin/p/6378110.html