C++智能指针

智能指针是 C++ 中用于管理动态分配的内存资源的一种重要工具。它们自动管理对象的生命周期,确保在不再需要对象时自动释放所占用的内存,从而避免内存泄漏和悬挂指针等问题。C++ 提供了三种主要的智能指针:shared_ptrunique_ptrweak_ptr

1. 智能指针的分类:

  • shared_ptr:多个 shared_ptr 可以共享同一个对象,并且会自动计数引用次数。当最后一个 shared_ptr 销毁时,对象会被自动删除。
  • unique_ptr:独占式智能指针,不能被复制,但可以转移所有权给另一个 unique_ptr
  • weak_ptr:弱引用指针,用于解决 shared_ptr 的循环引用问题,不会增加对象的引用计数。

2. 智能指针的作用及使用方法:

  • 自动管理资源生命周期,避免内存泄漏。
  • 确保资源在不再被使用时被正确释放,防止悬挂指针的问题。
  • 通过 shared_ptr 的引用计数机制,实现共享对象所有权,避免手动管理资源释放带来的复杂性和错误。

使用方法示例:

#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass(int value) : data(value) {
        std::cout << "Constructor called. Value: " << data << std::endl;
    }

    ~MyClass() {
        std::cout << "Destructor called. Value: " << data << std::endl;
    }

    void printData() const {
        std::cout << "Data: " << data << std::endl;
    }

private:
    int data;
};

int main() {
    // shared_ptr 使用示例
    std::shared_ptr<MyClass> shared1 = std::make_shared<MyClass>(10);
    std::shared_ptr<MyClass> shared2 = shared1; // 共享所有权

    shared1->printData();
    shared2->printData();

    // unique_ptr 使用示例
    std::unique_ptr<MyClass> unique = std::make_unique<MyClass>(20);
    // std::unique_ptr<MyClass> unique2 = unique; // 错误,unique_ptr 不能被复制,只能移动

    unique->printData();

    // weak_ptr 使用示例
    std::weak_ptr<MyClass> weak = shared1;
    if (auto shared3 = weak.lock()) {
        shared3->printData();
    } else {
        std::cout << "Object is no longer available." << std::endl;
    }

    return 0;
}

3. shared_ptr 的缺点及避免方法:

  • shared_ptr 有一个潜在的缺点是可能导致循环引用,当两个或多个对象通过 shared_ptr 彼此引用时,它们的引用计数永远不会减为零,对象永远不会被销毁,从而导致内存泄漏。这种情况被称为循环引用(circular reference)。

如何避免循环引用:

  • 使用 weak_ptr:在需要解决循环引用的情况下,可以使用 weak_ptr 来打破循环引用。weak_ptr 只是一个弱引用,它不会增加对象的引用计数,不会阻止对象被销毁。当需要访问对象时,可以使用 weak_ptrlock() 成员函数来获取一个有效的 shared_ptr,如果对象还存在,lock() 会返回一个有效的 shared_ptr,否则返回一个空的 shared_ptr

示例(使用 weak_ptr 避免循环引用):

#include <iostream>
#include <memory>

class B;

class A {
public:
    std::shared_ptr<B> bPtr;
};

class B {
public:
    std::weak_ptr<A> aWeakPtr;
};

int main() {
    std::shared_ptr<A> aPtr = std::make_shared<A>();
    std::shared_ptr<B> bPtr = std::make_shared<B>();

    aPtr->bPtr = bPtr;
    bPtr->aWeakPtr = aPtr;

    return 0;
}

在上面的示例中,AB 类相互引用,但是 B 类使用了 std::weak_ptr 来保存对 A 类的引用,这样就避免了循环引用问题。当 A 类的引用计数变为零时,它会被销毁,同时 B 类的 std::weak_ptr 也会自动失效,不会导致 B 类的引用计数不为零而无法销毁。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 导读 在《C++之指针扫盲》[https://mp.weixin.qq.com/s/zkjHSMj43qHRODf...
    FlyerGo阅读 324评论 0 1
  • 0、摘要 本文先讲了智能指针存在之前C++面临的窘境,并顺理成章地引出利用RAII技术封装普通指针从而诞生了智能指...
    嗯哼_9793阅读 775评论 0 0
  • C++智能指针 原文链接:http://blog.csdn.net/xiaohu2022/article/deta...
    小白将阅读 6,910评论 2 21
  • 智能指针 传统指针存在的问题需要手动管理内存容易发生内存泄露(忘记释放,出现异常等)释放之后产生野指针 智能指针就...
    lieon阅读 249评论 0 1
  • C++智能指针学习 [toc] 智能指针内存管理要解决的根本问题是:一个堆对象,在被多个对象引用时,如何释放资源的...
    tbmichael阅读 6,843评论 1 4