1、智能指针本质上是一个对象,这个对象可以像原生的一样来进行使用。原因是智能指针对象对应的类中,将指针相关的操作都进行了重载操作处理,所以才会达到这种像是原生的效果。
2、智能指针的意义:
现在C++开发库中最重要的类模板之一
C++中自动内存管理的主要手段
能够在很大程度上避开内存相关的问题
3、在QT中开发库中也提供了智能指针类模板,在STL标准库中也提供了,在c++的标准库忘了什么名了中也提供了智能指针类模板。所以智能指针类模板在C++中的地位很重要
4、STL中的智能指针类模板 auto_ptr,在memory这个头文件中。
(1)生命周期结束时,销毁指向的内存空间
(2)不能指向堆数组,只能指向堆对象(变量)
(3)一片堆空间只属于一个智能指针对象
(4)多个智能指针对象不能指向同一片堆空间
既然auto_ptr是一个类模板,所以使用时就要指定类型参数。如a:auto_ptr<Test> pt(new Test()); pt.get();可以返回pt所指向的空间的内存起始地址.
5、STL中的其他智能指针
(1)shared_ptr:带有引用计数机制,所以可以支持多个指针对象指向同一片内存空间
(2)weak_ptr:配合shared_ptr而引人的一种智能指针
(3)unique_ptr:一个指针对象只能指向一片内存空间,但是不能进行所有权的转移,所以就不能拷贝构造和赋值。
例:STL标准库中auto_ptr的使用
#include <iostream>
#include <string>
#include <memory> //auto_ptr这个智能指针类模板就在这个头文件中
using namespace std;
/*
* STL标准库中的auto_ptr智能指针类模板的使用。
* auto_ptr的特点:
* 生命周期结束时,销毁指向的内存空间
* 不能指向堆数组,只能指向堆对象(变量)
* 一片堆空间只属于一个智能指针对象
* 多个智能指针对象不能指向同一片堆空间
*/
class Test
{
private:
string m_name;
public:
Test(const char *name)
{
m_name = name;
cout << "Hello." << "I'm " << name << endl;
}
void print()
{
cout << "why_fangqingqing " << endl;
}
~Test()
{
cout << "Goodbye " << m_name << endl;
}
};
int main(void)
{
auto_ptr<Test> pt1(new Test("why"));
cout << "pt1 = " << pt1.get() << endl; //获取指向的内存空间的起始地址
pt1->print();
auto_ptr<Test> pt2(pt1); //pt2指向了pt1指向的内存空间,pt1释放掉指向的内存空间,这是auto_ptr的特点,一片内存空间只能由一个auto_ptr指针对象指向
cout << "pt1 = " << pt1.get() << endl; // 0
cout << "pt2 = " << pt2.get() << endl;
pt2->print();
return 0;
}
6、Qt中的智能指针类模板
(1)QPointer,在Qt中包含QPointer头文件就可以使用这个QPointer智能指针类模板了
@1:当其指向的对象被销毁时,它会被自动置空。(也就是说可以多个QPointer智能指针指向同一个对象,当这个对象被销毁的时候,所有的指向这个对象的QPointer指针都变为空了)
@2:析构时不会自动销毁所指向的对象。(也就是说QPoniter指针生命周期结束的时候,不会自动删除所指向的对象(堆空间),我们要手动的delete掉,手动delete一次之后,所有指向这个堆
空间的QPointer指针都会被置为空)
(2)QSharedPointer,在Qt中的QSharedPointer头文件中。
@1:引用计数型智能指针
@2:可以被自由的拷贝和赋值
@3:当引用计数为0时才删除指向的对象(也就是,当这个对象被一次QSharedPointer指针指向时,就会加一次这个对象的引用的次数。当指向这个对象的QSharedPointer指针少一个时,
就会减一次这个对象的引用次数,直到减到没有一个QSharedPointer指针指向这个对象时,也就是这个对象被QSharedPointer指针引用次数为0时,才会销毁这个对象)
在Qt开发中,所有自己写的类,都要去继承QObject这个顶层父类,也就是基类。
7、Qt中的其他智能指针类模板
(1)QWeakPointer
(2)QScopedPointer
(3)QSharedDataPointer
(4)QExplicitlySharedDataPointer
例:
#include <QPointer>
#include <QSharedPointer>
#include <QString>
#include <QDebug>
/*
* Qt开发库中的QPointer智能指针和QSharedPo智能指针类模板的使用。
* QPointer的特点:
* @1:当其指向的对象被销毁时,它会被自动置空。
* (也就是说可以多个QPointer智能指针指向同一个对象,当这个对象被销毁的时候,所有的指向这个对象的QPointer指针都变为空了)
* @2:析构时不会自动销毁所指向的对象。(也就是说QPoniter指针生命周期结束的时候,
* 不会自动删除所指向的对象(堆空间),我们要手动的delete掉,手动delete一次之后,所有指向这个堆空间的QPointer指针都会被置为空)
*/
/*
* QSharedPointer的特点:
* @1:引用计数型智能指针
* @2:可以被自由的拷贝和赋值
* @3:当引用计数为0时才删除指向的对象(也就是,当这个对象被一次QSharedPointer指针指向时,就会加一次这个
* 对象的引用的次数。当指向这个对象的QSharedPointer指针少一个时,就会减一次这个对象的引用次数,
* 直到减到没有一个QSharedPointer指针指向这个对象时,也就是这个对象被QSharedPointer指针引用次数为0时,才会销毁这个对象)
*/
class Test : public QObject //Qt中所有自己完成的类都要继承这个Qt中的QObject顶层父类,基类
{
private:
QString m_name;
public:
Test(const char *name)
{
m_name = name;
qDebug() << "Hello." << "I'm " << name;
}
void print()
{
qDebug() << "why_fangqingqing ";
}
~Test()
{
qDebug() << "Goodbye " << m_name;
}
};
int main(void)
{
QPointer<Test> pt1(new Test("why"));
QPointer<Test> pt2(pt1);
qDebug() << "pt1 = " << pt1;
qDebug() << "pt2 = " << pt2;
pt1->print();
pt2->print();
delete pt1; //要手动的去delete掉pt1所指向的堆空间。编译器不会自动的去销毁,当生命周期结束时,delete掉后,所有指向这个空间
//的QPointer指针都会被置为空。
qDebug() << "pt1 = " << pt1; //0
qDebug() << "pt2 = " << pt2; //0
qDebug() << endl;
QSharedPointer<Test> spt1(new Test("fangqingqing")); //这时这个堆空间的对象被QSharedPoin引用了一次
QSharedPointer<Test> spt2(spt1); //这时这个堆空间的对象被QSharedPoin引用又加了一次
qDebug() << "spt1 = " << spt1;
qDebug() << "spt2 = " << spt2;
spt1->print();
spt2->print();
return 0; //当那个堆空间的对象被QSharedPointer引用的次数减到0时,就会销毁这个堆空间的对象
}
7、自己实现一个智能指针类模板
#ifndef _SMARTPOINTER_H_
#define _SMARTPOINTER_H_
template
< typename T >
class Pointer
{
private:
T *mp;
public:
Pointer(T* p = NULL)
{
mp = p;
}
Pointer(const Pointer<T>& obj)
{
mp = obj.mp;
const_cast<Pointer<T>&>(obj).mp =NULL;
}
Pointer<T>& operator = (const Pointer<T>& obj)
{
if (this != &obj)
{
delete mp;
mp = obj.mp;
const_cast<Pointer<T>&>(obj).mp = NULL;
}
return *this;
}
T* get()
{
return mp;
}
T* operator -> ()
{
return mp;
}
T& operator * ()
{
return *mp;
}
~Pointer()
{
delete mp;
}
bool isNULL()
{
return (mp == NULL);
}
};
#endif
转载于:https://blog.51cto.com/whylinux/1846804