博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第六十一课、智能指针类模板
阅读量:6330 次
发布时间:2019-06-22

本文共 4697 字,大约阅读时间需要 15 分钟。

一、智能指针

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_template
class 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中提供了对智能指针的支持

 

转载于:https://www.cnblogs.com/gui-lin/p/6378110.html

你可能感兴趣的文章
transition过渡规定慢速开始,然后变快,然后慢速结束的过渡效果(cubic-bezier(0.25,0.1,0.25,1))。...
查看>>
JS基础知识
查看>>
关于Verilog HDL的一些技巧、易错、易忘点(不定期更新)
查看>>
用浮动IP实现高可用性,待续
查看>>
Strom(0.9.3)配置
查看>>
Python之Paramiko、前端之html学习_Day14
查看>>
HDU 3836 Equivalent Sets
查看>>
深入理解JVM读书笔记思维导图
查看>>
String字符串位置移动
查看>>
MySQL无法插入中文的解决方案
查看>>
bzoj2301
查看>>
react16 渲染流程
查看>>
Android游戏与应用开发最佳学习路线图
查看>>
Android应用打开外部文件
查看>>
hadoop生态搭建(3节点)-05.mysql配置_单节点
查看>>
堆和栈的区别
查看>>
网易2017春招笔试真题编程题集合(2)——赶去公司
查看>>
top命令
查看>>
JS-键盘事件之方向键移动元素
查看>>
Compass(更新中。。。)
查看>>