我与C++的爱恋:智能指针


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

🔥个人主页guoguoqiang. 🔥专栏我与C++的爱恋

Alt

1.为什么需要智能指针

int div() {
   
   
    int a, b;
    cin >> a >> b;
    if (b == 0)
        throw invalid_argument("除0错误"); 
    
    return a / b;
}
 
void Func() {
   
   
    // 1、如果p1这里new 抛异常会如何?
    // 2、如果p2这里new 抛异常会如何?
    // 3、如果div调用这里又会抛异常会如何?
    int* p1 = new int;
    int* p2 = new int;
    cout << div() << endl;
    
    delete p1;
    delete p2;
}
 
int main() {
   
   
    try
    {
   
   
        Func();
    }
    catch (exception& e)
    {
   
   
        cout << e.what() << endl;
    }
    return 0;
}

问题分析:上面的问题分析出来我们发现有什么问题?

动态内存分配没有释放:在 Func 函数中,您使用了 new int 来动态分配内存,但是在函数结束时,您没有释放这些内存。这将导致内存泄漏,因为这些动态分配的内存块不会被释放,最终可能会耗尽系统的内存资源。

异常安全性:在 div 函数中,如果除数 b 为0,会抛出一个 invalid_argument 异常。如果这个异常被抛出,那么在 Func 函数中分配的内存(p1 和 p2)不会被释放,这同样会导致内存泄漏。

main 函数中的异常处理:在 main 函数中,您捕获了所有类型的异常,包括 invalid_argument。但是,您没有检查捕获到的异常类型,这意味着任何类型的异常都会被打印出来。这可能会掩盖其他潜在的内存泄漏问题。

int div() {
   
   
    int a, b;
    cin >> a >> b;
    if (b == 0)
        throw invalid_argument("除0错误"); 
    
    int result = a / b;
    return result;
}
 
void Func() {
   
   
    int* p1 = new int;
    int* p2 = new int;
    
    try {
   
   
        cout << div() << endl;
    } catch (invalid_argument& e) {
   
   
        cout << e.what() << endl;
        delete p1;
        delete p2; // 释放动态分配的内存
        return; // 提前退出函数
    }
 
    delete p1;
    delete p2;
}
 
int main() {
   
   
    try {
   
   
        Func();
    } catch (exception& e) {
   
   
        cout << e.what() << endl;
    }
    return 0;
}

智能指针的引入:

double Division(int a, int b)
{
   
   
    // 当b == 0时抛出异常
    if (b == 0)
    {
   
   
        throw "Division by zero condition!";
    }
    return (double)a / (double)b;
}
 
struct A
{
   
   
    ~A() noexcept
    {
   
   
        cout << "~A()" << endl;
    }
 
    int _a1 = 0;
    int _a2 = 0;
};
 
template<class T>
class SmartPtr
{
   
   
public:
    // RAII
    SmartPtr(T* ptr)
        :_ptr(ptr)
    {
   
   }
 
    ~SmartPtr()
    {
   
   
        delete _ptr;
    }
 
    // 重载运算符,模拟指针的行为
    T& operator*()
    {
   
   
        return *_ptr;
    }
 
    T* operator->()
    {
   
   
        return _ptr;
    }
private:
    T* _ptr;
};
 
void Func()
{
   
   
    // 更好解决方案是智能指针
    shared_ptr<A> sp1(new A);
    SmartPtr<A> sp2(new A);
    sp1->_a1++;
    sp1->_a2++;
 
    //  智能指针麻烦的是拷贝
   // SmartPtr<A> sp3(sp1);
    
    //unique_ptr 不让拷贝
    //unique_ptr<A> sp3(sp1);
    
    //shared_ptr 支持拷贝
    shared_ptr<A> sp3(sp1);
 
    int len
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值