C++第13课 智能指针 (一)

1.shared_ptr

class MM 
{
public:
    MM() {}
    MM(string name, int age) :name(name), age(age) {}
    void print() 
    {
        cout << name << "\t" << age << endl;
    }
    ~MM() 
    {
        cout << "对象内存被释放" << endl;
    }
protected:
    string name;
    int age;
};

void testShared_ptr()
{
    //模板的类型:指针所指向的类型
    //切记不要用智能指针类的指针
    shared_ptr<int> pInt;
    if (!pInt)
    {
        cout << "空的智能指针对象" << endl;
    }
    //shared_ptr<int>* pInt2 = new shared_ptr<int>;  不要这样用
    //1.创建智能指针对象
    shared_ptr<int> pNum(new int(100));
    cout << pNum.use_count() << endl;
    cout << *pNum.get() << endl;
    cout << *pNum << endl;
    //cout << pNum[0] << endl;  没有重载
    //2.了解其中的一些成员
    /*
        2.1 get() 函数: 返回的是一个内置指针,指向管理的对象,不要做delete
        2.2 use_count(); 统计引用管理对象的智能指针对象数
        2.3 swap(): 交换
        2.4 reset(): 重新设置管理对象
    */
    //2.智能指针与类的关系
    {
        shared_ptr<MM> pMM(new MM("小可爱", 19));
        pMM->print();
        pMM.get()->print();
        //make_shared创建方式: make_shared函数参数是由MM的构造函数决定
        shared_ptr<MM>  xF = make_shared<MM>("小芳",18);
        xF->print();
    }
    //3.智能指针之间的关系,计数
    shared_ptr<MM>  p1(new MM("小美", 29));
    p1->print();
    cout << p1.use_count() << endl;
    shared_ptr<MM> p2 = p1;
    p2->print();
    cout << p2.use_count() << endl;
    p1.reset();
    cout << p1.use_count() << endl;
    //4.get方式注意: get获取的指针不要轻易的释放
    MM* p3 = p2.get();
    p3->print();
    //delete p3;   导致重复释放问题
    //p2->print(); p1和p2都不存在了
    //5.删除器这个东西 :就是一个释放内存的东西,
    //一般用只能指针对象管理的内存无法直接delete时候,需要手动释放
    //delete [] 指针;
    {
        shared_ptr<MM> pInt(new MM[10], [](MM* pMM) {delete[] pMM; });
        //delete 指针;
        //shared_ptr<FILE> fp(fopen("1.txt", "w+"), [](FILE* fp) {fclose(fp); });
    }
}

2.weak_ptr

class B;
class A 
{
public:
    A() {}
    ~A() { cout << "A" << endl; }
    //shared_ptr<B>  b;
    weak_ptr<B> b;
};
class B 
{
public:
    B() {};
    ~B() { cout << "B" << endl; }
    //shared_ptr<A> a;
    weak_ptr<A> a;
};
void testWeak_ptr() 
{
    /*
        1.weak_ptr是一个弱引用指针,不会累计计数
        2.weak_ptr只能从shared_ptr或者是weak_ptr构造而来
        3.主要是为了解决shared_ptr循环引用导致的内存析构问题
        注意点: 不可以使用* 或者->访问对象
                被赋值,不会更改shread_ptr中 use_count的值
    */
    {
        shared_ptr<A> aObject = make_shared<A>();
        shared_ptr<B> bObject = make_shared<B>();
        cout << aObject.use_count() << endl;
        cout << bObject.use_count() << endl;
        aObject->b = bObject;
        cout << aObject.use_count() << endl;
        bObject->a = aObject;
        cout << aObject.use_count() << endl;
    }
    {
        //weak_ptr<int> pInt(new int);  不能直接构建
        shared_ptr<int> p1(new int(100));
        weak_ptr<int> p2(p1);
        cout << p2.use_count() << endl;
        weak_ptr<int> p3(p2);
        cout << p3.use_count() << endl;
        p3.reset();
        cout << p2.use_count() << endl;
        //如何访问数据
        //cout << *p2 << endl;  不能使用* 和->
        //间接访问即可 先用weak_ptr访问shared_ptr
        //lock() 函数 返回一个shared_ptr
        cout << *p2.lock() << endl;
    }
}

3.unique_ptr

void testUnique_ptr() 
{
    /*
        unique_str
        1.禁止拷贝和赋值
        2.unique_ptr操作指针对象,任何时候都智能只有一个去操作
            2.1 move() 去移交所有权
            2.2 通过reset集合release函数去移交
    */
    unique_ptr<MM> p1(new MM("小甜心", 19));
    p1->print();
    //unique_ptr<MM> p2(p1);
    //p2 = p1;
    unique_ptr<MM> p3;
    p3 = move(p1);
    p3->print();
    //p1->print();        //p1已经没有这个权限(没有在指向MM对象)
    p1.reset(p3.release());
    p1->print();
    MM* p4 = p1.get();
    p4->print();        //自己用指针去操作的时候,尽量不要做内存释放,防止重复释放问题
}

 

posted @ 2021-09-11 16:17  Creature_lurk  阅读(44)  评论(0编辑  收藏  举报