C++11常用特性(下-智能指针)


一、智能指针

在传统 C++ 里我们只好使用 new 和 delete 去 『记得』对资源进行释放。而 C++11 引入了智能指针的概念,让程序员不再需要关心手动释放内存。

1.shared_ptr

引用计数这种计数是为了防止内存泄露而产生的。 基本想法是对于动态分配的对象,进行引用计数,每当增加一次对同一个对象的引用,那么引用对象的引用计数就会增加一次, 每删除一次引用,引用计数就会减一,当一个对象的引用计数减为零时,就自动删除指向的堆内存。

在这里插入图片描述

2.weak_ptr

weak_ptr是一种不控制所指向对象生存期的智能指针,协助shared_ptr工作,它指向一个由shared_ptr管理的对象。将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。并且一旦最后一个shared_ptr被销毁,其所指向的对象就会被释放,就算此时仍有weak_ptr指向该对象,也会被释放。
struct A;
struct B;
struct A {
    std::shared_ptr<B> pointer;
    ~A() {
        std::cout << "A 被销毁" << std::endl;
    }
};
struct B {
    std::shared_ptr<A> pointer;
    ~B() {
        std::cout << "B 被销毁" << std::endl;
    }
};
int main() {
    auto a = std::make_shared<A>();
    auto b = std::make_shared<B>();
    a->pointer = b;
    b->pointer = a;
}
上述例子,讲述的一个循环引用导致内存不能释放的问题

在这里插入图片描述

a和b两个结构体指针,在内部都有一个指向对方的指针,因此A和B的空间计数都是2,在程序结束时,仅仅是把两个计数都减一,引用计数不为0,因此并不会真正释放空间

解决办法就是使用weak_ptr
struct A;
struct B;
struct A {
    std::shared_ptr<B> pointer;
    ~A() {
        std::cout << "A 被销毁" << std::endl;
    }
};
struct B {
    std::weak_ptr<A> pointer;
    ~B() {
        std::cout << "B 被销毁" << std::endl;
    }
};
int main() {
    auto a = std::make_shared<A>();
    auto b = std::make_shared<B>();
    a->pointer = b;
    b->pointer = a;
}
weak_ptr仅仅是弱引用,因此最终A的计数会变成0,进行释放空间,B也会被释放

在这里插入图片描述

3.unique_ptr

一种独占的智能指针,它禁止其他智能指针与其共享同一个对象,unique_ptr对象始终是关联的原始指针的唯一所有者。我们无法复制unique_ptr对象,它只能移动,因此同一时间只会有一个对象可操作来保证安全
//初始化
std::unique_ptr<Task> taskPtr(new Task(22));
std::unique_ptr<Task> taskPtr = std::make_unique<Task>(34);
//转移
std::unique_ptr<Task> taskPtr2(new Task(55));
std::unique_ptr<Task> taskPtr4 = std::move(taskPtr2);
此时taskPtr2为空

// 编译错误 : unique_ptr 不能复制
std::unique_ptr<Task> taskPtr3 = taskPtr2; // Compile error
// 编译错误 : unique_ptr 不能复制
taskPtr = taskPtr2; //compile error
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值