C++智能指针学习代码笔记

 vscode

unique_ptr:

#include <iostream>
#include <memory>

using namespace std;
/*unique_ptr独享它指向的对象,unique_ptr被销毁时,指向对象也被销毁*/
/*
template <typename T, typename D = default_delete<T> >
class unique_ptr{
    public:
    explicit unique_ptr(pointer p) noexcept;  // 不可用于转换函数
    ~unique_ptr() noexcept;
    T& operator*() const;                     // 重载*操作符
    T* operator->() const noexcept;           // 重载->操作符。
    unique_ptr(const unique_ptr&) = delete;   // 禁用拷贝构造函数。
    unique_ptr& operator=(const unique_ptr&) = delete;  // 禁用赋值函数。
    unique_ptr(unique_ptr&&) noexcept;                  // 右值引用。
    unique_ptr& operator=(unique_ptr&&) noexcept;       // 右值引用
    //...
   private:
    pointer ptr;  // 内置的指针。
};
*/

class AA {
   public:
    string m_name;
    AA() { cout << m_name << "调用构造函数AA()。" << endl; }
    AA(const string& name) : m_name(name) {
        cout << "调用构造函数AA(" << m_name << ")" << endl;
    }
    ~AA() { cout << "调用析构函数~AA(" << m_name << ")" << endl;
     }
};

void text01() {  // 智能指针作用演示
    AA* p = new AA("西施");
    unique_ptr<AA> pu1(p);
    cout << "m_name =" << pu1->m_name << endl;
    cout << "m_name =" << (*pu1).m_name << endl;
}

void text02() {  // unique_ptr初始化 3种
    unique_ptr<AA> p0(new AA("西施1"));

    unique_ptr<AA> p1 = make_unique<AA>("西施2");

    AA* p = new AA("西施3");
    unique_ptr<AA> p2(p);

    // unique_ptr<AA> pu2 = p;              //构造函数不能隐式转换
    // unique_ptr<AA> pu3 = new AA("西施3")

    // unique_ptr<AA> pu4 = p0;            //禁用拷贝构造函数
    // p1 = p0;                            //禁用operator=

    /*为了防止程序员犯错,因为unique_ptr独享它指向的对象*/
}

/*
void text03() {     //不要同一个裸指针初始化多个unique_ptr对象
    AA* p = new AA("西施3");
    unique_ptr<AA> pu1(p);
    unique_ptr<AA> pu2(p);
    unique_ptr<AA> pu3(p);
}
*/

void text04() {
    AA* p = new AA("西施"); // 定义原始指针p,分配内存。
    unique_ptr<AA> pu(p);   // 创建智能指针对象,用于管理原始指针p
    cout << "裸指针的地址是:"       << p << endl;  
    // cout << "pu对象的值是:"         << pu << endl;  //VS没报错
    cout << "pu.get()输出的结果是:" << pu.get() << endl;
    cout << "pu的地址是:"           << &pu << endl;
}

void func(unique_ptr<AA>& pp) {
    cout << "name=" << pp->m_name << endl;
}

void test05() {
    AA *p = new AA("西施");
    unique_ptr<AA> pu(p);

    func(pu);  //无法值传递,只能引用传递
}

/*智能指针不支持 + - ++ --*/

int main() {
    // text01();
    // text02();
    text04();

    return 0;
}

shared_ptr 

#include <iostream>
#include <memory>

using namespace std;

/*shared_ptr共享它指向的对象,多个shared_ptr可指向相同的对象*/
/*新的shared_ptr与对象关联时,引用计数增加1*/
/*当shared_ptr超出作用域时,引用计数减一,当引用计数变为0时,没有任何shared_ptr与对象关联*/

/*shared_ptr的构造函数也是explicit,但是没有删除拷贝构造函数和赋值函数*/
class AA {
   public:
    string m_name;
    AA() { cout << m_name << "调用构造函数AA()。" << endl; }
    AA(const string& name) : m_name(name) {
        cout << "调用构造函数AA(" << m_name << ")" << endl;
    }
    ~AA() { cout << "调用析构函数~AA(" << m_name << ")" << endl; }
};

void text01() {  // 智能指针作用演示
    AA* p = new AA("西施");
    shared_ptr<AA> pu1(p);
    cout << "pu1.use_count() = " << pu1.use_count() << endl;
    cout << "m_name =" << pu1->m_name << endl;
    cout << "m_name =" << (*pu1).m_name << endl;
}

void text02() {  // shared_ptr初始化

    AA* p = new AA("西施");
    shared_ptr<AA> p0(p);

    shared_ptr<AA> p1 = p0; //拷贝构造


    cout << "p0.use_count() = " << p0.use_count() << endl;
    cout << "p1.use_count() = " << p1.use_count() << endl;

    cout << "m_name =" << p0->m_name << endl;
    cout << "m_name =" << p1->m_name << endl;
}

void test03() {  //用已经存在的shared_ptr拷贝,左值-1 右值+1
    shared_ptr<AA> pa0(new AA("西施a"));
    shared_ptr<AA> pa1 = pa0;
    shared_ptr<AA> pa2 = pa0;
    cout << "pa0.use_count() = " << pa0.use_count() << endl;  // 3
    cout << "pa1.use_count() = " << pa1.use_count() << endl;  // 3
    cout << "pa2.use_count() = " << pa2.use_count() << endl;  // 3

    shared_ptr<AA> pb0(new AA("西施b"));
    shared_ptr<AA> pb1 = pb0;
    cout << "pb0.use_count() = " << pb0.use_count() << endl;  // 2
    cout << "pb1.use_count() = " << pb1.use_count() << endl;  // 2

    pb1 = pa1;//pb1不管理“西施b”了,去管理pa1管理的“西施a”了
    cout << "pa0.use_count() = " << pa0.use_count() << endl;  // 4
    cout << "pa1.use_count() = " << pa1.use_count() << endl;  // 4
    cout << "pa2.use_count() = " << pa2.use_count() << endl;  // 4
    cout << "pb0.use_count() = " << pb0.use_count() << endl;  // 1
    cout << "pb1.use_count() = " << pb1.use_count() << endl;  // 4

    pb0 = pa1;//pb0不管理“西施b”了,去管理pa1管理的“西施a”了
    cout << "pa0.use_count() = " << pa0.use_count() << endl;  // 5
    cout << "pa1.use_count() = " << pa1.use_count() << endl;  // 5
    cout << "pa2.use_count() = " << pa2.use_count() << endl;  // 5
    cout << "pb0.use_count() = " << pb0.use_count() << endl;  // 5
    cout << "pb1.use_count() = " << pb1.use_count() << endl;  // 5
}

/*智能指针不支持 + - ++ --*/

int main() {
    // text01();
    // text02();
    test03();
    return 0;
}

weak_ptr 

#include <iostream>
#include <memory>

using namespace std;
/*weak_ptr是为了配合shared_ptr引入的,它指向一个由shared_ptr管理的资源但不影响资源的生命周期*/

class AA {
   public:
    string m_name;
    AA() { cout << m_name << "调用构造函数AA()。" << endl; }
    AA(const string& name) : m_name(name) {
        cout << "调用构造函数AA(" << m_name << ")" << endl;
    }
    ~AA() { cout << "调用析构函数~AA(" << m_name << ")" << endl; }
    shared_ptr<AA> m_sp;  // 如果循环引用,引用计数永远无法归0,资源不会被释放
    weak_ptr<AA> m_wp;  // weak_ptr不影响引用计数
};

// 如果循环引用,引用计数永远无法归0,资源不会被释放
void test01() {
    shared_ptr<AA> pa(new AA("西施a"));
    shared_ptr<AA> pb(new AA("西施b"));

    cout << "pa.use_count() = " << pa.use_count() << endl;  // 1
    cout << "pb.use_count() = " << pb.use_count() << endl;  // 1

    // pa->m_sp = pb;
    // pb->m_sp = pa;

    pa->m_wp = pb;
    pb->m_wp = pa;

    cout << "pa.use_count() = " << pa.use_count() << endl;
    cout << "pb.use_count() = " << pb.use_count() << endl;
}

int main() {
    test01();
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值