[C++11]_[初级]_[shared_ptr的简单使用]

场景

  1. C++11之前,使用auto_ptr只能适用于 new 出来的对象,为此我还专门创建了一些工具类来释放对象.使用智能指针的方式释放malloc出来的堆空间,C++11出现后可以使用shared_ptr来管理C指针了.

  2. 多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用,在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃,所以为了省时间一般都是任由这个内存泄漏发生.当然也可以经过复杂的设计,由一个监控线程来统一删除,但这样会增加代码量和复杂度.这下好了,shared_ptr 可以方便的解决问题,因为它是引用计数和线程安全的.

参考

std::shared_ptr

说明

shared_ptr的所有的方法(包括复制构造函数 和 赋值重载)都能被多线程中的不同shared_ptr实例(拥有相同的对象)安全的调用而不需要额外的同步操作.

使用

创建方式

// 方式1,使用 make_shared 支持不定参数
auto sp = std::make_shared<B>(12,13);

struct D
{
    void operator()(void* data)
    {
        std::cout << "free: " << (int*)data << std::endl;
        free(data);
    }
};

A* a = (A*)malloc(sizeof(A));
a->i = 10;
std::cout << (int*)a << std::endl;
//方式2,3:外部创建指针对象传入
//D 是自定义释放函数或类型
std::shared_ptr<A> ar(a,D());

//方式4: 复制了指针,增加引用计数
std::shared_ptr<Base> lp = p;

例子1 自定义释放函数.

struct A
{
    int i;
};

struct D
{
    void operator()(void* data)
    {
        std::cout << "free: " << (int*)data << std::endl;
        free(data);
    }
};

// 使用shared_ptr来调用特殊的释放函数.
void TestCPointer()
{
    A* a = (A*)malloc(sizeof(A));
  a->i = 10;
  std::cout << (int*)a << std::endl;
    std::shared_ptr<A> ar(a,D());
    // 也可以这样
    //std::shared_ptr<A> ar(a,free);
    std::cout << ar.get()->i << std::endl;
}

例子2 多线程访问

#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>
#include <stdlib.h>
#include <Windows.h>

struct Base
{
    Base() { std::cout << " Base::Base()\n"; }
    // Note: non-virtual destructor is OK here
    ~Base() { std::cout << " Base::~Base()\n"; }
};

struct Derived: public Base
{
    Derived() { std::cout << " Derived::Derived()\n"; }
    ~Derived() { std::cout << " Derived::~Derived()\n"; }
};

void thr(std::shared_ptr<Base> p)
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::shared_ptr<Base> lp = p; // thread-safe, even though the
                                  // shared use_count is incremented
    {
        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_count() = " << lp.use_count() << '\n';
    }
}

struct A
{
    int i;
};


void Free(void* data)
{
    std::cout << "free: " << (int*)data << std::endl;
    free(data);
}

struct D
{
    void operator()(void* data)
    {
        std::cout << "free: " << (int*)data << std::endl;
        free(data);
    }
};

// 使用shared_ptr来调用特殊的释放函数.
void TestCPointer()
{
    A* a = (A*)malloc(sizeof(A));
    a->i = 10;
    std::cout << (int*)a << std::endl;
    // 自定义释放函数.
    std::shared_ptr<A> ar(a,D());
    // 也可以这样
    //std::shared_ptr<A> ar(a,free);
    std::cout << ar.get()->i << std::endl;
}

int main()
{
    std::shared_ptr<Base> p = std::make_shared<Derived>();


    std::cout << "Created a shared Derived (as a pointer to Base)\n"
              << " p.get() = " << p.get()
              << ", p.use_count() = " << p.use_count() << '\n';
    std::thread t1(thr, p), t2(thr, p), t3(thr, p);
    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.detach();
    t2.detach();
    t3.detach();

    while(1)
    {
        if (p.use_count() == 1)
        {
            break;
        }
        Sleep(500);
    }
    std::cout << "All threads completed, the last one deleted Derived\n";
    //TestCPointer();
    return 0;
}

输出:

Base::Base()
Derived::Derived()
Created a shared Derived (as a pointer to Base)
p.get() = 0x323f8, p.use_count() = 1
Shared ownership between 3 threads and released
ownership from main:
p.get() = 0x323f8, p.use_count() = 4
local pointer in a thread:
lp.get() = 0x323f8, lp.use_count() = 5
local pointer in a thread:
lp.get() = 0x323f8, lp.use_count() = 5
local pointer in a thread:
lp.get() = 0x323f8, lp.use_count() = 3
All threads completed, the last one deleted Derived
Derived::~Derived()
Base::~Base()

你可能感兴趣的:(例子,使用,C++11,shared-ptr,共享指针)