C++智能指针

本文介绍了C++中的三种智能指针:unique_ptr、shared_ptr和weak_ptr,它们如何自动管理内存,避免内存泄漏和悬挂指针问题。unique_ptr独占所有权,shared_ptr共享所有权并跟踪引用,而weak_ptr提供弱引用,用于处理循环引用和其他复杂场景。
摘要由CSDN通过智能技术生成

智能指针

        智能指针是封装了原始指针的智能对象,自动管理所指向的资源,避免内存泄漏和悬挂指针等问题,C++11引入了四种智能指针:unique_ptr、shared_ptr、weak_ptr、auto_ptr(C++17中已被弃用)。

1.unique_ptr

unique_ptr是一种独占式的智能指针,它拥有对象的唯一所有权,并且在对象生命周期结束时自动释放该对象。unique_ptr不能被复制和赋值,因此可以避免资源重复释放和悬挂指针等问题。unique_ptr适用于需要独占对象的情况,例如动态分配的内存和IO资源等。

#include <iostream>
#include <memory>

int main() {
    std::unique_ptr<int> ptr = std::make_unique<int>(5); //创建一个指向int类型的unique_ptr并初始化为5
    std::cout << "ptr = " << *ptr << std::endl; //输出指针所指向的值

    //动态分配一个数组,并将其绑定到unique_ptr
    std::unique_ptr<int[]> arr_ptr(new int[3]); 
    arr_ptr[0] = 1;
    arr_ptr[1] = 2;
    arr_ptr[2] = 3;
    std::cout << "arr_ptr[0] = " << arr_ptr[0] << std::endl; //输出数组第一个元素的值

    //通过unique_ptr释放动态分配的内存
    arr_ptr.reset(); //释放数组所占用的内存

    return 0;
}
 

2.shared_ptr

shared_ptr是一种共享式的智能指针,它可以与多个指针共享对象,使用引用计数来跟踪对象的引用,并在所有引用都失效时自动释放对象。shared_ptr可以被复制和赋值,并且可以自动管理动态分配的内存。

#include <iostream>
#include <memory>

class Person {
public:
    Person(const std::string& name) : name_(name) {}
    ~Person() {
        std::cout << "Destroying " << name_ << std::endl;
    }
    void greet() const {
        std::cout << "Hello, my name is " << name_ << std::endl;
    }
private:
    std::string name_;
};

int main() {
    std::shared_ptr<Person> person1 = std::make_shared<Person>("Alice");
    std::shared_ptr<Person> person2 = person1;

    person1->greet();
    person2->greet();

    person1.reset();

    if(person2) {
        std::cout << "person2 is still alive!" << std::endl;
        person2->greet();
    }
    
    return 0;
}
 

程序输出为:

Hello, my name is Alice
Hello, my name is Alice
Destroying Alice
person2 is still alive!
Hello, my name is Alice
 

Person是一个拥有名称的类,shared_ptr用于管理Person对象的生命周期。在main函数中,首先创建了一个Person对象并将其分配给一个shared_ptr(person1),然后又将相同的对象指针分配给另一个shared_ptr(person2),因此同一对象现在由两个指针共享。

我们使用->运算符来调用Person类中的函数,并使用reset函数来撤销person1指针。最后,我们检查person2指针是否仍然有效,并调用greet函数,以确保Person对象仍然存在。

3.weak_ptr

weak_ptr是一种弱引用智能指针,它是一种指向某个对象的指针,但它不会增加对象的引用计数,也不会拥有对象的所有权。相反,它只是提供了一种访问被其他shared_ptr所控制的对象的方法。如果被其它shared_ptr所控制的对象已经被销毁,那么weak_ptr会自动置为空,避免了悬空指针的问题。

weak_ptr一般在以下几种场景下使用:

  1. 在使用shared_ptr的循环引用中,一般使用weak_ptr打破循环引用,避免造成内存泄漏。
  2. 在缓存中使用weak_ptr,可以避免因缓存中的对象被占用而导致的内存过多占用。
  3. 在异步操作中使用weak_ptr,可以避免异步操作完成后访问到已经被销毁的对象而导致程序崩溃。

可以通过lock()函数获取weak_ptr指向的对象的shared_ptr,从而访问被其它shared_ptr控制的对象,或者判断对象是否已经被销毁。如果weak_ptr已经失效或者指向的对象已经被销毁,lock()函数会返回空的shared_ptr

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass(int value) : m_value(value) {
        std::cout << "Constructing MyClass object with value " << m_value << std::endl;
    }

    void doSomething() {
        std::cout << "MyClass object with value " << m_value << " is doing something!" << std::endl;
    }

private:
    int m_value;
};

int main() {
    // Create a shared pointer to a MyClass object with value 42
    std::shared_ptr<MyClass> myClassSharedPtr = std::make_shared<MyClass>(42);

    // Create a weak pointer to the same MyClass object
    std::weak_ptr<MyClass> myClassWeakPtr = myClassSharedPtr;

    // Use the shared pointer to call the doSomething() method
    myClassSharedPtr->doSomething();

    // Check if the weak pointer still points to the MyClass object
    if (std::shared_ptr<MyClass> myClassSharedPtr2 = myClassWeakPtr.lock()) {
        std::cout << "Weak pointer is still valid!" << std::endl;

        // Use the shared pointer obtained from the weak pointer to call the doSomething() method
        myClassSharedPtr2->doSomething();
    } else {
        std::cout << "Weak pointer is no longer valid!" << std::endl;
    }

    return 0;
}
 

在这个代码中,我们创建了一个shared_ptr指向MyClass对象,然后又创建了一个weak_ptr指向同一个MyClass对象。然后我们使用shared_ptr调用了MyClass对象的doSomething()方法。接着,我们通过lock()方法检查了weak_ptr是否仍然指向同一个MyClass对象,如果是,我们使用lock()方法返回的shared_ptr再次调用了doSomething()方法。如果不是,则说明MyClass对象已经被销毁了,我们就不能再使用它了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值