程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> [C++11]_[初級]_[shared_ptr的簡單使用]

[C++11]_[初級]_[shared_ptr的簡單使用]

編輯:C++入門知識

[C++11]_[初級]_[shared_ptr的簡單使用]


場景

C++11之前,使用auto_ptr只能適用於 new 出來的對象,為此我還專門創建了一些工具類來釋放對象.使用智能指針的方式釋放malloc出來的堆空間,C++11出現後可以使用shared_ptr來管理C指針了.

多線程程序經常會遇到在某個線程A創建了一個對象,這個對象需要在線程B使用,在沒有shared_ptr時,因為線程A,B結束時間不確定,即在A或B線程先釋放這個對象都有可能造成另一個線程崩潰,所以為了省時間一般都是任由這個內存洩漏發生.當然也可以經過復雜的設計,由一個監控線程來統一刪除,但這樣會增加代碼量和復雜度.這下好了,shared_ptr 可以方便的解決問題,因為它是引用計數和線程安全的.

說明

shared_ptr的所有的方法(包括復制構造函數 和 賦值重載)都能被多線程中的不同shared_ptr實例(擁有相同的對象)安全的調用而不需要額外的同步操作.

使用

創建方式

// 方式1,使用 make_shared 支持不定參數
auto sp = std::make_shared(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 ar(a,D());

//方式4: 復制了指針,增加引用計數
std::shared_ptr
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 ar(a,D());
    // 也可以這樣
    //std::shared_ptr ar(a,free);
    std::cout << ar.get()->i << std::endl;
}

例子2 多線程訪問

#include 
#include 
#include 
#include 
#include 
#include 
#include 

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 p)
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::shared_ptr lp = p; // thread-safe, even though the
                                  // shared use_count is incremented
    {
        static std::mutex io_mutex;
        std::lock_guard 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 ar(a,D());
    // 也可以這樣
    //std::shared_ptr ar(a,free);
    std::cout << ar.get()->i << std::endl;
}

int main()
{
    std::shared_ptr
p = std::make_shared(); 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()

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved