记录C++学习 17 智能指针

智能指针

new在堆上分配内存,delete删除内存,智能指针是实现这一过程自动化的一种方式

unique_ptr

作用域指针,不能被复制,因为如果复制后,两个指针同时指向一个内存,如果其中一个死了,会释放那块内存,所以另一指针指向一段被释放的内存。

举例

#include <iostream>

class Entity
{
private:
    int x;
public:
    Entity()
    {
        std::cout << "create entity" << std::endl;
    }
    ~Entity()
    {
        std::cout << "destroy entity" << std::endl;
    }
    void Print()
    {

    }
};

int main()
{
    {
        std::unique_ptr<Entity> entity(new Entity);
        entity->Print();
    }
    std::cin.get();
}

也可以更改为以下代码,防止内存泄漏

#include <iostream>

class Entity
{
private:
    int x;
public:
    Entity()
    {
        std::cout << "create entity" << std::endl;
    }
    ~Entity()
    {
        std::cout << "destroy entity" << std::endl;
    }
    void Print()
    {

    }
};

int main()
{
    {
        std::unique_ptr<Entity> entity = std::make_unique<Entity>(); 
        entity->Print();
    }
    std::cin.get();
}

当作用煜结束后,entity会被自动摧毁 

这也是最简单的智能指针,但不能复制和拷贝,如下,不能将entity复制给e0

#include <iostream>

class Entity
{
private:
    int x;
public:
    Entity()
    {
        std::cout << "create entity" << std::endl;
    }
    ~Entity()
    {
        std::cout << "destroy entity" << std::endl;
    }
    void Print()
    {

    }
};

int main()
{
    {
        std::unique_ptr<Entity> entity = std::make_unique<Entity>();
        std::unique_ptr<Entity> e0 = entity;
        entity->Print();
    }
    std::cin.get();
}

会报错,如果我们需要复制,我们需要用到共享指针

shared_ptr

举例

通过shared_ptr可以实现复制

#include <iostream>

class Entity
{
private:
    int x;
public:
    Entity()
    {
        std::cout << "create entity" << std::endl;
    }
    ~Entity()
    {
        std::cout << "destroy entity" << std::endl;
    }
    void Print()
    {

    }
};

int main()
{
    {
        std::shared_ptr<Entity>e0;
        {
            std::shared_ptr<Entity>entity = std::make_shared<Entity>();
            e0 = entity;
        }
    }
    std::cin.get();
}
 

当我们debug时,可以发现,std::shared_ptr<Entity>e0;没有分配内存给e0所以没用调用构造函数,std::shared_ptr<Entity>entity = std::make_shared<Entity>();时出现create entity,引用计数为1, e0 = entity;后引用计数为2,然后在}之后,entity被消灭,但并没有调用~Entity(),这是因为,e0还持有对Entity的引用,当第2个}后,e0也被消灭,此时引用计数减为0,没有对Entity类的引用,所以调用~Entity(),出现destroy entity

 weak_ptr

不会增加引用计数,它不会让底层对象保持存活,通常和shared_ptr一起用

举例

当把上面代码中shared_ptr改成weak_ptr时,代码如下

#include <iostream>

class Entity
{
private:
    int x;
public:
    Entity()
    {
        std::cout << "create entity" << std::endl;
    }
    ~Entity()
    {
        std::cout << "destroy entity" << std::endl;
    }
    void Print()
    {

    }
};

int main()
{
    {
        std::weak_ptr<Entity>e0;
        {
            std::shared_ptr<Entity>entity = std::make_shared<Entity>();
            e0 = entity;
        }
    }
    std::cin.get();
}

 和之前不同,在std::shared_ptr<Entity>entity = std::make_shared<Entity>();时,调用构造函数,引用计数为1,e0 = entity;后引用计数不变,为1,在}后引用计数减为0,没有对Entity类的引用,调用~Entity(),出现destroy entity

总结

当要声明一个堆分配对象,并且不希望自己来清理,就应该使用智能指针,unique_ptr有更小的内存开销(单纯因为栈内存不够大时常用),如果需要在对象之间共享,用shared_ptr,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值