cpp11学习笔记01:智能指针

auto_ptr(隐患,可能释放2次), shared_ptr, unique_ptr, weak_ptr。

详细的理论可以大家可以参考其他资料,这里一些代码片段方便自己平时工作查阅。

shared_ptr

#include <iostream>
#include <memory>
#include <string>

class TestA
{
    public:
        TestA(int n, std::string name): member(n), m_name(name){};

        void show() {
            std::cout << "Init class, id: " << member << " name: " << m_name << std::endl;
        }

        void update_name(std::string name) {
            m_name = name;
        }
    
    private:
        int member;
        std::string m_name;
};


void pass_by_value(std::shared_ptr<TestA> a)
{
    std::cout << "------------------------------------------------------------- \n";
    std::cout << "pass by value function \n";
    a->show();
    std::cout << "use count: " << a.use_count() << std::endl;
    std::cout << "------------------------------------------------------------- \n";
}


void pass_by_ref(std::shared_ptr<TestA> &a)
{
    std::cout << "------------------------------------------------------------- \n";
    std::cout << "pass by ref function \n";
    a->show();
    std::cout << "use count: " << a.use_count() << std::endl;
    std::cout << "------------------------------------------------------------- \n";
}

std::shared_ptr<TestA> get_share_ptr()
{
    std::shared_ptr<TestA> local = std::make_shared<TestA>(10, "local");
    return local;
}

int main()
{
    // 构建方式1
    std::shared_ptr<TestA> ptr1 = std::make_shared<TestA>(1, "bobo");
    ptr1->show();

    // 查看引用计数
    std::cout << "use count: " << ptr1.use_count() << std::endl;

    // 赋值
    std::shared_ptr<TestA> ptr2 = ptr1;
    auto ptr3 = ptr1;
    
    std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;
    std::cout << "ptr2 use count: " << ptr2.use_count() << std::endl;
    std::cout << "ptr3 use count: " << ptr3.use_count() << std::endl;

    // 删除某一个指针观察引用计数
    ptr2 = nullptr;      // ptr2.reset();
    
    std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;
    std::cout << "ptr3 use count: " << ptr3.use_count() << std::endl;

    // 因为共享某一块内存,可以观察值
    std::cout << "------------------------------------------------------------- \n";
    ptr1->update_name("tom");
    ptr1->show();
    ptr3->show();

    std::cout << "------------------------------------------------------------- \n";
    pass_by_value(ptr1);
    std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;
    std::cout << "ptr3 use count: " << ptr3.use_count() << std::endl;

    std::cout << "------------------------------------------------------------- \n";
    pass_by_ref(ptr1);
    std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl;
    std::cout << "ptr3 use count: " << ptr3.use_count() << std::endl;

    std::cout << "------------------------------------------------------------- \n";
    std::shared_ptr<TestA> ptr4 = get_share_ptr();
    std::cout << "ptr4 use count: " << ptr4.use_count() << std::endl;

    std::cout << "Finished! \n";
    return 0;
}

unique_ptr

#include <iostream>
#include <memory>

class TestA
{
    public:
        TestA(int n): member(n){};

        void show() {
            std::cout << "init class, n: " << member << std::endl;
        }
    
    private:
        int member;
};


void pass_by_value(std::unique_ptr<TestA> a) 
{
    std::cout << "pass by value \n";
    a->show();
}

void print_by_ref(std::unique_ptr<TestA> &a)
{
    std::cout << "print by ref \n";
    a->show();
    a.reset();      // 清空指针
}

void print_by_ref_const(const std::unique_ptr<TestA> &a)
{
    std::cout << "print by ref \n";
    a->show();
    // a.reset();   // const 引用,不可以修改值
}

std::unique_ptr<TestA> return_by_value()
{
    std::cout << "return by value function \n";
    std::unique_ptr<TestA> local = std::make_unique<TestA>(6);
    return local;
}

int main()
{
    // 构造方式1
    TestA *a_ptr = new TestA(1);
    std::unique_ptr<TestA> a_unique_ptr{a_ptr};
    a_unique_ptr->show();

    // 构造方式2
    std::unique_ptr<TestA> unique_ptr_02{new TestA(2)};
    unique_ptr_02->show();

    // 构造方式3
    std::unique_ptr<TestA> unique_ptr_03 = std::make_unique<TestA>(3);
    unique_ptr_03->show();

    // 函数传递值
    std::unique_ptr<TestA> unique_pass_by_value = std::make_unique<TestA>(4);
    pass_by_value(std::move(unique_pass_by_value));     // 转换为右值

    // 传递引用
    std::unique_ptr<TestA> unique_pass_by_ref = std::make_unique<TestA>(5);
    print_by_ref(unique_pass_by_ref);

    // 函数返回值
    std::unique_ptr<TestA> return_by_value_ptr{std::move(return_by_value())};
    return_by_value_ptr->show();

    return 0;
}

补充

1. weak_ptr用来避免shared_ptr互相引用无法释放。lock方法可以查看对象是否释放,设计本身就是服务于shared_ptr,核心功能就是不增加引用计数。

class Test 
{
    private:
        std::shared_ptr<Test> m_friend;     // 为了避免循环引用,改为weak_ptr即可
}

2. 不可以将shared_ptr转换为unique_ptr。 unique_ptr可以转换为shared_ptr,通过std::move。

3. 引用计数和指向变量的指针作为一种临界资源,如果不加锁,那么在多线程情况下会出现线程安全问题。

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值