一、智能指针
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