c++11 unique_ptr && shared_ptr

#include <array>
#include <cassert>
#include <chrono>
#include <fstream>
#include <iostream>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>

namespace std {

template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
}  // namespace std

void contains_main()
{
    // array
    {
        std::cout << "---------------std arrary contains\n";
        std::array<int, 5> stdarray = { 1, 2, 6, 4, 20 };
        for (auto it = stdarray.begin(); it != stdarray.end(); it++) {
            std::cout << *it << "\t";
        }
        std::cout << "\n";
    }
}

struct sBase {
    sBase()
    {
        std::cout << "sBase::sBase()\n";
    }
    virtual ~sBase()
    {
        std::cout << "sBase::~sBase()\n";
    }
};

struct sDerived : public sBase {
    sDerived()
    {
        std::cout << "sDerived::sDerived()\n";
    }
    virtual ~sDerived()
    {
        std::cout << "sDerived::~sDerived()\n";
    }
};

void thr(std::shared_ptr<sBase> p)
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::shared_ptr<sBase> lp = p;
    {
        static std::mutex           io_mutex;
        std::lock_guard<std::mutex> lk(io_mutex);
        std::cout << "local pointer in a thread:\n"
                  << "lp.get() = " << lp.get() << "lp.use_conut() = " << lp.use_count() << "\n";
    }
}

struct B {
    virtual void bar()
    {
        std::cout << "B::bar()\n";
    }
    virtual ~B() = default;
};

struct D : B {
    D()
    {
        std::cout << "D:D()\n";
    }
    ~D()
    {
        std::cout << "D:~D()\n";
    }
    void bar() override
    {
        std::cout << "D:bar()\n";
    }
};

std::unique_ptr<D> pass_through(std::unique_ptr<D> p)
{
    p->bar();
    return p;
}

void close_file(std::FILE* fp)
{
    std::cout << "deleter\n";
    std::fclose(fp);
}

/**
 *  1、尽量不使用相同的原始指针来创建多个shared_ptr对象
 *
 *
 *
 *
 */

void error_shared_ptr()
{
    {
        int*                 rawPtr = new int();
        std::shared_ptr<int> ptr_1(rawPtr);
        std::shared_ptr<int> ptr_2(rawPtr);
        //当我们去清理ptr_2时,清除原始指针,那么ptr_1就会成为nullptr
    }
    {
        int                  x = 12;
        std::shared_ptr<int> ptr(&x);
        //这里shared_ptr关联的内存是堆,当析构时执行delete删除堆上的对象会引起程序崩溃。
        //所以建议用std::make_shared<>来创建shared_ptr指针
    }
}

void smart_ptr_main()
{
    //拥有共享对象所有权的语义的智能指针
    // shared_ptr 多个智能指针可以共享一个对象,对象末尾一个拥有着销毁对象的责任,并清理与该对象的多有资源
    {
        std::cout << "---------------std shared_ptr\n";
        std::shared_ptr<sBase> p = std::make_shared<sDerived>();

        std::cout << "create a shared sDerived(as a pointer to sBase)\n"
                  << "p.get() = " << p.get() << ", p.use_count() = " << p.use_count() << "\n";

        std::thread t1(thr, p), t2(thr, p), t3(thr, p);
        p.reset();  //这里会把计数减1 p.reset(new sDerived());也可以重新指向新指针
        std::cout << "create a shared sDerived(as a pointer to sBase)\n"
                  << "p.get() = " << p.get() << ", p.use_count() = " << p.use_count() << "\n";

        std::cout << "shared ownership between 3 threads and released\n"
                  << "ownership from main:\n"
                  << "p.get() = " << p.get() << ", p.use_count() = " << p.use_count() << "\n";

        t1.join();
        t2.join();
        t3.join();
        std::cout << "all threads completed, the last one deleted sDerived\n";
    }

    // unique_ptr 拥有独立对象所有权的智能指针
    {
        std::cout << "---------------std shared_ptr\n";
        {
            std::cout << "unqiue ownership semantics demo\n";
            auto p = std::make_unique<D>();
            auto q = pass_through(std::move(p));
            assert(!p);  //现在p不占任何内容并保有空指针
            q->bar();
        }  //代码段在此结束,q会自动释放掉
        {
            std::cout << "runtime polymorphism demo\n";
            std::unique_ptr<B> p = std::make_unique<D>();  // p 是占有D的unique_ptr 作为指向基类的指针
            p->bar();                                      //虚派发

            std::vector<std::unique_ptr<B>> v;
            v.push_back(std::make_unique<D>());
            v.push_back(std::move(p));
            v.emplace_back(new D);
            for (auto& p : v) {
                p->bar();
            }
        }
        {
            std::cout << "custom deleter demo\n";
            std::ofstream("demo.txt") << 'x';
            std::unique_ptr<std::FILE, void (*)(std::FILE*)> fp(std::fopen("demo.txt", "r"), close_file);
            if (fp) {
                std::cout << ( char )std::fgetc(fp.get()) << "\n";
            }
        }  //这里会调用自定义的deleter函数 close_file, 只有fopen成功

        {
            std::cout << "custom lambda-expression deleter demo\n";
            std::unique_ptr<D, std::function<void(D*)>> p(new D, [](D* ptr) {
                std::cout << "destorying from a custom deleter...\n";
                delete ptr;
            });
            p->bar();
        }  //这里调用上述lambda 并销毁D

        {
            std::cout << "array form of unique_ptr demo\n";
            std::unique_ptr<D[]> p(new D[ 3 ]);
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中,`unique_ptr`、`shared_ptr`、`weak_ptr`是三种常用的智能指针,用于管理动态分配的内存,避免内存泄漏和悬空指针等问题。 1. `unique_ptr`:是一种独占式智能指针,表示一个对象的所有权只能被一个`unique_ptr`持有,不能被其他指针或引用所共享。当`unique_ptr`超出作用域或被显式释放时,它所指向的对象将被自动销毁。例如: ```cpp std::unique_ptr<int> p(new int(10)); ``` 2. `shared_ptr`:是一种共享式智能指针,表示一个对象的所有权可以被多个`shared_ptr`共享。每个`shared_ptr`维护一个引用计数器,当引用计数器变为0时,它所指向的对象将被自动销毁。`shared_ptr`还支持自定义删除器,可以在对象销毁时执行特定的操作。例如: ```cpp std::shared_ptr<int> p = std::make_shared<int>(10); std::shared_ptr<int> q = p; ``` 3. `weak_ptr`:是一种弱引用智能指针,不能直接访问所指向的对象,只能通过调用`lock()`方法获得一个指向所指对象的`shared_ptr`。当`weak_ptr`所指向的对象已经被销毁时,`lock()`方法将返回一个空的`shared_ptr`。`weak_ptr`主要用于解决`shared_ptr`的循环引用问题,避免内存泄漏。例如: ```cpp std::shared_ptr<int> p = std::make_shared<int>(10); std::weak_ptr<int> q = p; std::shared_ptr<int> r = q.lock(); ``` 这些智能指针都定义在`<memory>`头文件中,并且都是模板类,可以用于管理各种类型的动态分配内存。在实际开发中,应尽量使用智能指针来管理内存,避免手动管理内存所带来的麻烦和风险。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值