四种智能指针的使用

auto_ptr<>, unique_ptr<>, shared_ptr<>, weak_ptr<>

参考:

https://changkun.de/modern-cpp/zh-cn/05-pointers/

================================================

1. auto_ptr<>

#include<memory>
#include <iostream>
using namespace std;

struct Test
{
    /* data */
    int ta = 1;
    std::string ts = "HelloCpp";

};

int main() {

    auto_ptr<Test> p1(new Test());
    cout << p1.get()->ta << endl;
    cout << (*p1).ta << endl;

    auto_ptr<Test> p2 = p1;
    if (p1.get() != nullptr) { cout << p1.get()->ta << endl;}
    else {cout << "p1 is nullptr!!!" << endl;}

    cout << p2.get()->ta << endl;

    p2.reset(new Test());
    cout << p2.get()->ta << endl;

    Test* p3 = p2.release();  // release() 返回一个指针
    cout << p3->ts << endl;

    p2.reset(); // reset() 会把当前智能指针内部的指针置0,或者输入新指针,如 p2.reset(Test*)
    cout << p2.get() << endl;


}

 

 

2. shared_ptr<>

  • 引用计数规则
#include<memory>
#include <iostream>
using namespace std;

struct Test
{
    /* data */
    int ta = 1;
    std::string ts = "HelloCpp";

};


int main() {

    std::shared_ptr<Test> a = std::make_shared<Test>();

    Test* pa = a.get(); // 获得 shared_ptr 对象内部包含的普通指针
    cout << a->ta << endl;
    cout << a->ts << endl;
    cout << (*a).ta << endl; 
    cout << (*a).ts << endl; 
    cout << pa->ta << endl; 
    cout << pa->ts << endl; 


    cout << "============" << endl;
    cout << a.unique() << endl; //判断当前是否还有其他的share_ptr对象指向它,返回bool值
    cout << (a) << endl;

    cout << a.use_count() << endl;
    a.reset();
    cout << a.use_count() << endl;

}

 

 

3. unique_ptr<>

  • make_unique 的实现
  • template<typename T, typename ...Args>
    std::unique_ptr<T> make_unique(Args&& ...args) {
        return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
    }

#include <iostream>
#include
<memory> using namespace std; struct Foo { Foo() {std::cout << "Foo ctor" << std::endl;} ~Foo() {std::cout << "Foo dtor" << std::endl;} void foo() {std::cout << "Foo function" << std::endl;} }; void fun(const Foo&) { std::cout << "fun(const Foo&)" << std::endl; } int main() { std::unique_ptr<Foo> p1(std::make_unique<Foo>()); // std::make_unique<> 在C++14后加入 fun(*p1); if (p1) p1->foo(); cout << "==========" << endl; std::unique_ptr<Foo> p2(std::move(p1)); fun(*p2); fun(*p1); cout << p2.get() << endl; cout << p1.get() << endl; if (p2) p2->foo(); if (p1) p1->foo(); cout << "==========" << endl; p1 = std::move(p2); fun(*p2); fun(*p1); cout << p2.get() << endl; cout << p1.get() << endl; if (p2) p2->foo(); if (p1) p1->foo(); }


 输出结果:

Foo ctor

fun(const Foo&)

Foo function

==========

fun(const Foo&)

fun(const Foo&)

0x130deb0

0

Foo function

==========

fun(const Foo&)

fun(const Foo&)

0

0x130deb0

Foo function

Foo dtor

 

 

4. weak_ptr<>

引入weak_ptr的原因:解决share_ptr 相互引用时出现的引用计数不为0导致的内存泄漏问题。

#include <iostream>
#include <memory>
using namespace std;
    
struct A;
struct B;

struct A
{
    /* data */
    std::shared_ptr<B> pB;
    ~A() {
        std::cout << "Destroy A" << std::endl;
    }
};

struct B
{
    /* data */
    std::shared_ptr<A> pA;   //解决内存泄漏的办法是: std::weak_ptr<A> pA;
    ~B() { 
        std:cout << "Destroy B" << std::endl;
    }
};


void func(shared_ptr<A>& a, shared_ptr<B>& b) { cout << "a.use_cout() " << a.use_count() << endl; cout << "b.use_cout() " << b.use_count() << endl; a->pB = b; b->pA = a; cout << "a.use_cout() " << a.use_count() << endl; cout << "b.use_cout() " << b.use_count() << endl; } int main() {
    auto a = std::make_shared<A>();
    auto b = std::make_shared<B>();
  func(a, b); 

cout << "a.use_cout() " << a.use_count() << endl;
cout << "b.use_cout() " << b.use_count() << endl;

return 0;
}

输出结果:

  a.use_cout() 1
  b.use_cout() 1
  a.use_cout() 2
  b.use_cout() 2

此时,当 main() 函数结束以后,a 和 b 被销毁,但是原本来在 a 和 b 类中的智能指针 pA 和 pB 仍然指向对方,即两者的计数都为 1,因此造成内存泄漏。

解决办法是将其中一个 智能指针类成员改成 weak_ptr 类型,即弱引用指针,weak_ptr不会引起计数增加。

 

posted @ 2021-12-23 17:24  算是一个初学者  阅读(253)  评论(0编辑  收藏  举报