C++学习:智能指针

介绍

智能指针(Smart Pointer)是C++中的一种类模板,用于自动管理动态分配的内存,确保在不再需要时自动释放,从而避免内存泄漏和悬空指针等问题。智能指针通过RAII(Resource Acquisition Is Initialization)惯用法来管理资源,其基本思想是资源的生命周期绑定到对象的生命周期。

种类

std::unique_ptr:

独占所有权的智能指针,意味着同一时间内只能有一个指针指向某个动态分配的对象。当std::unique_ptr销毁时,它所指向的对象也会被销毁。

例子如下:

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "MyClass Constructor" << std::endl; }
    ~MyClass() { std::cout << "MyClass Destructor" << std::endl; }
    void display() { std::cout << "Display" << std::endl; }
};

int main() {
    std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>();
    ptr1->display();

    // std::unique_ptr<MyClass> ptr2 = ptr1; // 错误,不能复制
    std::unique_ptr<MyClass> ptr2 = std::move(ptr1); // 转移所有权
    if (ptr1 == nullptr) {
        std::cout << "ptr1 is null" << std::endl;
    }

    ptr2->display();

    return 0;
}

注:使用的时候所使用的头文件是memory。

std::make_unique 是C++14引入的一个函数模板,用于创建std::unique_ptr实例。相比直接使用newstd::make_unique有以下几个优点:

  1. 简洁性:代码更简洁,更易读。
  2. 异常安全:在资源分配时,如果抛出异常,std::make_unique能更好地管理内存,避免内存泄漏。

后续的make_xxxx同理

运行结果如下:

只能通过转移所有权  而不能通过直接赋值

std::shared_ptr

共享所有权的智能指针,多个std::shared_ptr可以指向同一个对象,并使用引用计数来跟踪有多少指针指向该对象。当最后一个std::shared_ptr销毁时,指向的对象才会被销毁。

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "MyClass Constructor" << std::endl; }
    ~MyClass() { std::cout << "MyClass Destructor" << std::endl; }
    void display() { std::cout << "Display" << std::endl; }
};

int main() {
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    std::shared_ptr<MyClass> ptr2 = ptr1; // 共享所有权

    ptr1->display();
    std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;
    std::cout << "ptr2 use count: " << ptr2.use_count() << std::endl;

    ptr2.reset(); // 释放ptr2的所有权
    std::cout << "After reset ptr2" << std::endl;
    std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;

    return 0;
}

运行结果如下

可以看见最开始计数的时候 是有两个指针指向该对象的,之后释放ptr2 计数会变为1

std::weak_ptr

弱引用智能指针,不会影响所指向对象的引用计数。通常与std::shared_ptr一起使用,用于解决循环引用问题。

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "MyClass Constructor" << std::endl; }
    ~MyClass() { std::cout << "MyClass Destructor" << std::endl; }
    void display() { std::cout << "Display" << std::endl; }
};

int main() {
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    std::weak_ptr<MyClass> weakPtr = ptr1; // 创建弱引用

    if (auto ptr2 = weakPtr.lock()) { // 尝试提升为shared_ptr
        ptr2->display();
    } else {
        std::cout << "Object is no longer available" << std::endl;
    }

    ptr1.reset(); // 释放shared_ptr
    if (auto ptr2 = weakPtr.lock()) {
        ptr2->display();
    } else {
        std::cout << "Object is no longer available" << std::endl;
    }

    return 0;
}

运行结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值