智能指针分析

文章讨论了C++中内存泄漏的问题,由于语言特性,C++没有内置的垃圾回收机制。通过示例展示了如何通过创建智能指针类来解决这个问题,智能指针通过重载操作符(->和*)并在析构函数中释放内存,确保堆空间的正确管理,防止内存泄漏。此外,文章强调了智能指针应仅用于指向堆内存中的对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内存泄漏 (臭名昭著的 Bug)

动态申请堆空间,用完后不归还

C++ 语言中没有垃圾回收的机制

指针无法控制所指堆空间的生命周期

内存泄漏

#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;
}

第 27 行,我们在堆空间上分配了 5 个 Test 类对象的空间,但是我们在 for 循环结束前,没有释放  p 所指向堆空间的内存,每次 for 循环执行完一次,指针 p 的生命周期就消失了,但是它所指向的堆空间并没有释放,也没有指针指向这片堆空间了,导致这片堆空间后续没办法释放,造成内存泄漏

程序运行结果如下图所示:

我们需要什么?

需要一个特殊的指针

指针生命周期结束时主动释放堆空间

一片堆空间最多只能由一个指针标识

杜绝指针运算和指针比较

解决方案

重载指针特征操作符 ( -> 和 * )

只能通过类的成员函数重载

重载函数不能使用参数

只能定义一个重载函数

智能指针

#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)
    {
        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;
}

Pointer 是一个智能指针类,重载了指针操作 -> 和 * 操作符,在析构函数中,会释放指向的堆空间内存;这个智能指针类,在进行拷贝构造和拷贝赋值的操作时,会接管拷贝指针的所有权,保证一片堆空间只被一个智能指针管理

第 69 行,p1 会管理分配出来堆空间上的一个 Test 类对象的内存空间;第 71 行,p2 接管了 p1 所管理的堆空间内存

p1 和 p2 现在是一个类对象,所以在其生命周期结束的时候,会自动调用析构函数,释放所管理的堆空间内存

程序运行结果如下图所示:

智能指针的使用军规

只能用来指向堆空间中的对象或者变量

小结

指针特征操作符 ( -> 和 * ) 可以被重载

重载指针特征符能够使用对象代替指针

智能指针只能用于指向堆空间中的内存

智能指针的意义在于最大程度的避免内存问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值