1,智能指针本质上是一个对象,这个对象可以像原生的指针一样使用,因为智能指 针相关的类通过重载的技术将指针相关的操作符都进行了重载,所以智能指针对象可以像原生指针一样操作,今天学习智能指针类模板,通过这个类模板就可以淘汰原生的指针了;

2,智能指针的意义:

1,现代 C++ 开发库中最重要的类模板之一;

1,STL 标准库提供;

2,Qt 平台提供;

2,是 C++ 中自动内存管理的主要手段;

3,能够在很大程度上避开内存相关的问题;

1,内存泄漏,测试阶段很难发现,应用程序运行很久才能够发现,一般是申请堆空间内存忘记释放造成的;

2,多次指针释放,结果也是不确定的,有可能程序马上死掉,有可能过一段时间死掉并且这是就无法找问题究竟出在哪一行代码上;

3,STL 中的智能指针 auto_ptr:

1,生命周期结束时,销毁指向的内存空间;

1,智能指针是一个对象,有生命周期,这个特点解决内存泄漏问题;

2,不能指向堆数组,只能指向堆对象(变量);

1,这是一个缺点,但是另一个角度来看,使用堆空间的数组可以使用其他的类,比如上节课中的 HeapArray 类;

3,一片堆空间只属于一个智能指针对象;

1,避免多次释放同一个指针;

4,多个智能指针对象不能指向同一片堆空间;

1,同上面一点;

4,auto_ptr 使用初探:

1,main.cpp 文件:

 #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); // pt 转移了对堆空间的控制权,指向 NULL; cout << "pt = " << pt.get() << endl;
cout << "pt1 = " << pt1.get() << endl; pt1->print(); return ;
}

 2,输出结果:

 Hello, D.T.Software.
pt = 0x877c008
I'm D.T.Software. pt =
pt1 = 0x877c008
I'm D.T.Software.
Goodbye, D.T.Software.

5,STL 中的其它智能指针:

1,shared_ptr:

1,带有引用计数机制,支持多个指针对象指向同一片内存;

2,weak_ptr:

1,配合 shared_ptr 而引入的一种智能指针;

3,unique_ptr:

1,一个指针对象指向一片内存空间,不能拷贝构造和赋值;

2,auto_ptr 的进化版,不能进行控制权的转移,通过不能拷贝构造和赋值实现;

6,Qt 中的智能指针:

1,QPointer:

1,当其指向的对象被销毁(释放)时,它会被自动置空;

1,可以使用多个 QPointer 智能指针指向同一个对象,当这个对象被销毁的时候,所有的智能指针对象都变为空,这可以避免多次释放和野指针的问题,非常好;

2,析构时不会自动销毁所指向的对象;

1,也就是当 QPointer 对象生命周期完结的时候,不会自动销毁堆空间中的对象,需要手动销毁;

2,这个是它的缺点,以后编程要注意这一点和其它智能指针不同;

2,QSharedPointer(和 STL 中的同名指针类模板相似):

1,引用计数型智能指针;

1,引用计数的对象是堆空间申请的对象;

2,可以被自动第拷贝和赋值;

3,当引用计数为 0 时才删除指向的对象;

1,这个智能指针对象生命周期结束后,引用计数减一;

3,Qt 还要提供自己的智能指针是和它的架构开发思想相关,因为 Qt 有自己的内存管理思想,但是这些思想并没有在 STL 中实现,所以说为了将这种内存管理思想贯彻到 Qt 中的方方面面,所以 Qt 才开发了自己的智能指针类模板,最常用和最具代表性的就是上面两类;

7,Qt 中的智能指针编程实验:

1,main.cpp 文件:

 #include <QPointer>
#include <QSharedPointer>
#include <QDebug> class Test : public QObject // Qt 开发中都要将类继承自 QObject;
{
QString m_name;
public:
Test(const char* name)
{
qDebug() << "Hello, " << name << "."; m_name = name;
} void print()
{
qDebug() << "I'm " << m_name << ".";
} ~Test()
{
qDebug() << "Goodbye, " << m_name << ".";
}
}; int main()
{
QPointer<Test> pt(new Test("D.T.Software"));
QPointer<Test> pt1(pt);
QPointer<Test> pt2(pt); pt->print();
pt1->print();
pt2->print(); delete pt; // 手工删除,这里只用删除一次就可,上述三个指针都指向NULL; qDebug() << "pt = " << pt; // QObject(0x0)
qDebug() << "pt1 = " << pt1; // QObject(0x0)
qDebug() << "pt2 = " << pt2; // QObject(0x0) qDebug() << endl; QSharedPointer<Test> spt(new Test("Delphi Tang")); // 引用计数是相对于 Text("Delphi Tang") 对象而言;
QSharedPointer<Test> spt1(spt);
QSharedPointer<Test> spt2(spt); spt->print();
spt1->print();
spt2->print(); return ;
}

 2,输出结果:

 Hello, D.T.Software.
I'm "D.T.Software".
I'm "D.T.Software".
I'm "D.T.Software".
Goodbye, "D.T.Software".
pt = QObject(0x0)
pt1 = QObject(0x0)
pt2 = QObject(0x0) Hello, D.T.Software.
I'm "D.T.Software".
I'm "D.T.Software".
I'm "D.T.Software".
Goodbye, "D.T.Software".

8,Qt 中的其它智能指针:

1,QweakPointer;

2,QScopedPointer;

3,QScopedArrayPointer;

4,QSharedDataPointer;

5,QExplicitlySharedDataPointer;

9,创建智能指针类模板编程实验:

1,SmartPointer.h 文件:

 #ifndef _SMARTPOINTER_H_
#define _SMARTPOINTER_H_ template
< typename T >
class SmartPointer
{
T* mp;
public:
SmartPointer(T* p = NULL)
{
mp = p;
} SmartPointer(const SmartPointer<T>& obj)
{
mp = obj.mp;
const_cast<SmartPointer<T>&>(obj).mp = NULL;
} SmartPointer<T>& operator = (const SmartPointer<T>& obj)
{
if( this != &obj )
{
delete mp;
mp = obj.mp;
const_cast<SmartPointer<T>&>(obj).mp = NULL;
} return *this;
} T* operator -> ()
{
return mp;
} T& operator * ()
{
return *mp;
} bool isNull()
{
return (mp == NULL);
} T* get()
{
return mp;
} ~SmartPointer()
{
delete mp;
}
}; #endif

 2,main.cpp 文件:

 #include <iostream>
#include <string>
#include "SmartPointer.h" 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()
{
SmartPointer<Test> pt(new Test("D.T.Software")); cout << "pt = " << pt.get() << endl; pt->print(); cout << endl; SmartPointer<Test> pt1(pt); cout << "pt = " << pt.get() << endl;
cout << "pt1 = " << pt1.get() << endl; pt1->print(); return ;
}

 3,输出结果:

 Hello, D.T.Software.
pt = 0x9881008
I'm D.T.Software. pt =
pt1 = 0x9881008
I'm D.T.Software.
Goodbye, D.T.Software.

4,参照了 auto_ptr 的设计,也会发生堆空间控制权的转移,发生在拷贝构造函数和符赋值操作符中;

10,小结:

1,智能指针 C++ 中自动内存管理的主要手段;

2,智能指针在各种平台上都有不同的表现形式;

1,以类模板方式出现;

3,智能指针能够尽可能的避开内存相关的问题;

1,内存泄漏;

2,多次释放;

4,STL 和 Qt 中都提供了对智能指针的支持;

C++中的智能指针类模板的更多相关文章

  1. 智能指针类模板(上)——STL中的智能指针

    智能指针类模板智能指针本质上就是一个对象,它可以像原生指针那样来使用. 智能指针的意义-现代C++开发库中最重要的类模板之一-C++中自动内存管理的主要手段-能够在很大程度上避开内存相关的问题 1.内 ...

  2. 智能指针类模板(中)——Qt中的智能指针

    Qt中的智能指针-QPointer .当其指向的对象被销毁时,它会被自动置空 .析构时不会自动销毁所指向的对象-QSharedPointer .引用计数型智能指针 .可以被自由的拷贝和赋值 .当引用计 ...

  3. OSG中的智能指针

    在OpenSceneGraph中,智能指针(Smart pointer)的概念指的是一种类的模板,它针对某一特定类型的对象(即Referenced类及其派生类)构建,提供了自己的管理模式,以避免因为用 ...

  4. ATL和vc++中的智能指针(分别是CComPtr和_com_ptr_t)

    一.智能指针的概念 智能指针是一个类,不是指针,智能指针在所包含的指针不再被使用时候会自动释放该所包含指针所占用的系统资源,而不用手动释放. 原理:智能指针封装了包含指针的AddRef()函数和Rel ...

  5. 标准库中的智能指针shared_ptr

    智能指针的出现是为了能够更加方便的解决动态内存的管理问题.注:曾经记得有本书上说可以通过vector来实现动态分配的内存的自动管理,但是经过试验,在gcc4.8.5下是不行的.这个是容易理解的,vec ...

  6. C++ 中的智能指针-基础

    简介 在现代 C++ 编程中,标准库包含了智能指针(Smart pointers). 智能指针用来确保程序不会出现内存和资源的泄漏,并且是"异常安全"(exception-safe ...

  7. C++中的智能指针

    一.动态内存管理 通常我们创建动态内存的时候,需要自己管理好内存,也就是说,new出来的对象一定要注意释放掉.下面通过例子可以看到这个问题所在: struct BBE{ int X; int Y; v ...

  8. Boost中的智能指针(转)

    这篇文章主要介绍 boost中的智能指针的使用.(转自:http://www.cnblogs.com/sld666666/archive/2010/12/16/1908265.html) 内存管理是一 ...

  9. C++中的智能指针、轻量级指针、强弱指针学习笔记

    一.智能指针学习总结 1.一个非const引用无法指向一个临时变量,但是const引用是可以的! 2.C++中的delete和C中的free()类似,delete NULL不会报"doubl ...

随机推荐

  1. NGUI的滚动条的制作(scroll bar script)

    一,我们添加一个sprite,添加一个box collider,然后添加一个scroll bar script,我们来看看scroll bar script的属性 看到background和forgr ...

  2. JS书目推荐(私教推荐)

    下面几本书是私教推荐的,从入门到提高,从易到难,想找电子版的可以去下面这个网站找找,挺多书籍的 鸠摩搜书https://www.jiumodiary.com/ JavaScript编程精解 (第二版) ...

  3. java随机数Math.random()

    double random=Math.random();//返回[0,1)随机数 (int)(Math.random()*6)//返回0-5:随机数 (int)(Math.random()*6+1)/ ...

  4. eclipse 设置注释模板

    window->preference->java->code  styple->code template->Comments Types /** * @author $ ...

  5. linux性能分析工具Cpu

  6. @RestController vs @Controller

    package com.example.demo.controller; import java.util.HashMap; import java.util.Map; import org.spri ...

  7. 微信小程序(13)--页面滚动到某个位置添加类效果

    微信小程序页面滚动到某个位置添加类,盒子置顶效果. <!-- vh,是指CSS中相对长度单位,表示相对视口高度(Viewport Height),1vh = % * 视口高度 --> &l ...

  8. java 指定日期后n天

    RT 算时间本来就是我的弱项:不废话了,贴代码 想传什么参数自己在改改就ok,传入String,放回String public class Text { public static void main ...

  9. zookeeper与kafka安装搭建

    1.2181:对cline端提供服务 2.3888:选举leader使用 3.2888:集群内机器通讯使用(Leader监听此端口)

  10. 外包项目测试工作量评估指南&外包项目测试验收流程

    ## ### 外包项目测试工作量评估指南 1.目的        编写本指导书的目的旨在为我公司进行测试外包服务工作进行指导,帮助项目经理和相关人员编写测试方案.评估工作量.制定测试计划和测试策略等, ...