你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C++——智能指针的学习

[复制链接]
gaosmile 发布时间:2020-8-29 23:18
一、智能指针的学习:
1、内存泄漏:
关于内存泄漏这个问题,一般都会牵扯到指针这个话题,也就是我们常说的动态内存分配;然而在程序员手动进行堆空间的分配时(指针无法控制所指堆空间的生命周期,),往往在写完程序的时候,程序员一不小心就忘了释放已经手动分配的内存大小,导致软件Bug不断(也就是内存泄漏)。
在C++语言里面又没有垃圾回收的机制(不像高级语言Java有自动的垃圾回收机制,),所以程序员在写程序的时候,经常会发生刚才上面说的那种情况,这里我们来看一个例子:
#include <iostream>
#include <string>

using namespace std;

class Test
{
    int i;
public:
    Test(int i)
    {
        this->i = i;
    }
    int value()
    {
        return i;
    }
    ~Test()
    {
    }
};

int main()
{
    for(int i=0; i<5; i++)
    {
        Test* p = new Test(i);
        
        cout << p->value() << endl;
    }
   
    return 0;
}

输出结果:
txp@ubuntu:~$ ./a.out
0
1
2
3
4

注解:上面分配的堆空间,没有释放掉
2、我们需要什么?
  • 需要一个特殊的指针: 智能指针对象,通过类的普通构造函数完成;
  • 指针生命周期结束的时候,主动释放堆空间
  • 一片堆空间最多只能由一个指针标识:避免多次释放内存,通过拷贝构造函数和赋值操作符完成;
  • 杜绝指针运算和指针比较

3、智能指针的使用:
  • 重载指针特征操作符(->和*)
  • 只能通过类的成员函数重载
  • 重载函数不能使用参数
  • 只能定义一个重载函数

代码实践:
#include <iostream>
#include <string>

using namespace std;

class Test
{
    int i;
public:
    Test(int i)
    {
        cout << "Test(int i)" << endl;
        this->i = i;
    }
    int value()
    {
        return i;
    }
    ~Test()
    {
        cout << "~Test()" << endl;
    }
};

class Pointer
{
    Test* mp;
public:
    Pointer(Test* p = NULL)// 1,智能指针对象,通过类的普通构造函数完成;
    {
        mp = p;
    }
    Pointer(const Pointer& obj)//避免多次释放内存,通过拷贝构造函数和赋值操作符完成;
    {
        mp = obj.mp;// 传递堆空间的控制;
        const_cast<Pointer&>(obj).mp = NULL;//初始化对象不管之前的;堆空间了,做所有权的转移,保证堆空间最多只能由一个对象被标识;
    }
    Pointer& operator = (const Pointer& obj)
    {
        if( this != &obj )
        {
            delete mp;
            mp = obj.mp;
            const_cast<Pointer&>(obj).mp = NULL;
        }
        
        return *this;
    }
    Test* operator -> () // 返回指针,准备指示;
    {
        return mp;
    }
    Test& operator * () // 解引用,返回对象;
    {
        return *mp;
    }
    bool isNull()
    {
        return (mp == NULL);
    }
    ~Pointer()
    {
        delete mp;
    }
};

int main()
{
    Pointer p1 = new Test(0);
   
    cout << p1->value() << endl;
   
    Pointer p2 = p1;
   
    cout << p1.isNull() << endl;
   
    cout << p2->value() << endl;
   
    return 0;
}

输出结果:
txp@ubuntu:~$ ./a.out
Test(int i)
0
1
0
~Test()
总结提示:智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放
二、总结:
  • 指针特征操作符(->和*)可以被重载
  • 重载指针特征符能够使用对象代替指针
  • 智能指针只能用指向堆空间中的内存
  • 智能指针的意义在于最大程度的避免内存问题

好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。

收藏 评论0 发布时间:2020-8-29 23:18

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版