C++之智能指针 !!! 一文读懂智能指针 !!!

两种智能指针的区别和选择方式

std::unique_ptrstd::shared_ptr 是C++标准库中的两种不同类型的智能指针,它们有一些关键的区别。以下是它们之间的主要区别:

  1. 所有权:

    • std::unique_ptr 拥有独占所有权,一个 std::unique_ptr 实例是唯一能够拥有和管理其指向对象的所有权。当 std::unique_ptr 被销毁时,它拥有的对象也会被销毁。
    • std::shared_ptr 允许多个 std::shared_ptr 实例共享同一个对象的所有权。通过引用计数机制,当最后一个 std::shared_ptr 被销毁时,才会销毁共享的对象。
  2. 性能开销:

    • std::unique_ptr 通常比 std::shared_ptr 更轻量,因为它不需要维护引用计数。
    • std::shared_ptr 使用引用计数来跟踪共享的所有权,可能会带来额外的性能开销。
  3. 内存管理:

    • std::unique_ptr 适用于独占所有权的场景,一般用于管理单一对象或数组。
    • std::shared_ptr 适用于共享所有权的场景,可用于在多个地方访问相同的对象。
  4. 创建方式:

    • std::unique_ptr 使用 std::make_unique 或直接使用 new 操作符创建。
    • std::shared_ptr 使用 std::make_shared 或直接使用 new 操作符创建。
  5. 传递所有权:

    • std::unique_ptr 可以通过移动语义来传递所有权,不能直接进行拷贝。
    • std::shared_ptr 可以通过拷贝来传递所有权,引用计数会相应地增加。
  6. 循环引用:

    • std::unique_ptr 不涉及循环引用的问题,因为它是独占所有权的。
    • std::shared_ptr 可能引入循环引用的问题,需要注意使用 std::weak_ptr 来打破循环引用。
  7. 线程安全性:

    • std::unique_ptr 不提供多线程访问的保护。
    • std::shared_ptr 提供了引用计数的原子操作,可以在多线程环境下安全使用。

在选择使用 std::unique_ptr 还是 std::shared_ptr 时,取决于你的设计需求。如果能够确定对象拥有独占的所有权,并且不需要共享,那么 std::unique_ptr 是更轻量和合适的选择。如果需要在多个地方共享对象,并希望方便地传递所有权,那么 std::shared_ptr 是一个更适合的选择。

share_ptr 示例 独占权所以不能建多个指针

#include <iostream>
#include <memory>

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

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

    void someFunction() {
        std::cout << "Some function. Value: " << value << std::endl;
    }

private:
    int value;
};

int main() {
    // 创建一个 std::shared_ptr,多个指针共享所有权的 MyClass 对象
    std::shared_ptr<MyClass> sharedPtr = std::make_shared<MyClass>(42);

    // 使用 std::shared_ptr 指向的资源
    sharedPtr->someFunction();

    // 在此处创建一个新的 std::shared_ptr,共享相同的资源
    std::shared_ptr<MyClass> sharedPtr2 = sharedPtr;

    sharedPtr2->someFunction();

        // 在此处创建一个新的 std::shared_ptr,共享相同的资源
    std::shared_ptr<MyClass> sharedPtr3 = sharedPtr;

    sharedPtr3->someFunction();

    // sharedPtr , sharePtr2 和 sharedPtr3 在此处被销毁,动态分配的 MyClass 对象的析构函数被调用

    return 0;
}

unique_ptr 指针示例 没有独占权可以建多个指针共享内存,引用计数为0自动销毁

#include <iostream>
#include <memory>

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

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

    void someFunction() {
        std::cout << "Some function. Value: " << value << std::endl;
    }

private:
    int value;
};

int main() {
    // 创建一个 std::unique_ptr,拥有独占所有权的 MyClass 对象
    std::unique_ptr<MyClass> uniquePtr = std::make_unique<MyClass>(42);

    // 使用 std::unique_ptr 指向的资源
    uniquePtr->someFunction();

    // 在此处创建一个新的 std::unique_ptr,尝试共享所有权(编译错误)
    //std::unique_ptr<MyClass> anotherUniquePtr = uniquePtr;  // 错误!

    // uniquePtr 在此处被销毁,动态分配的 MyClass 对象的析构函数被调用

    return 0;
}

两种指针比较 实例

#include <iostream>
#include <memory>

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

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

    void someFunction() {
        std::cout << "Some function. Value: " << value << std::endl;
    }

private:
    int value;
};

int main() {
    // 使用 std::unique_ptr
    {
        std::cout << "----- Using std::unique_ptr 1st 42 -----" << std::endl;

        // 创建一个 std::unique_ptr,拥有一个动态分配的 MyClass 对象
        std::unique_ptr<MyClass> uniquePtr = std::make_unique<MyClass>(42);

        // 使用 std::unique_ptr 指向的资源
        uniquePtr->someFunction();

    

        std::cout << std::endl;

        // 使用 std::shared_ptr
        {
            std::cout << "----- Using std::shared_ptr 2nd 24 -----" << std::endl;

            // 创建一个 std::shared_ptr,拥有一个动态分配的 MyClass 对象
            std::shared_ptr<MyClass> sharedPtr = std::make_shared<MyClass>(24);

            // 使用 std::shared_ptr 指向的资源
            sharedPtr->someFunction();

            // 在此处创建一个新的 sharedPtr2,与 sharedPtr 共享资源
            std::shared_ptr<MyClass> sharedPtr2 = sharedPtr;

            // sharedPtr 和 sharedPtr2 在此处被销毁,动态分配的 MyClass 对象的析构函数被调用
        }

        // unique_ptr 1st 在此处被销毁,动态分配的 MyClass 对象的析构函数被调用

    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值