首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++11 智能指針 unique_ptr 使用場景與獨佔所有權語義詳解

     編輯:關於C++

std::unique_ptr 是 C++11 引入的獨佔所有權智能指針,不可複製,只能移動。旨在替代已棄用的 auto_ptr,提供數組支持(delete[])、自定義刪除器、零開銷抽象。

一、核心特性

特性說明
所有權同一時刻僅一個 unique_ptr 擁有對象
複製構造/賦值刪除(=delete),不可複製
移動構造/賦值默認實現,所有權轉移
刪除器默認 delete,支援 delete[] 及自定義 callable
線程安全無引用計數,非線程安全,性能接近裸指針
適用場景單線程、明確所有權轉移、RAII 資源管理

二、三種典型用法示例

1. 單對象 + 自動銷毀

{
    std::unique_ptr p1(new Foo); // 構造
} // 離開作用域自動 delete p1

2. 動態數組

{
    std::unique_ptr p2(new Foo[4]); // 構造數組
} // 自動 delete[] p2

3. 自定義刪除器

struct D { void operator()(Foo* p) { std::cout << "custom delete\n"; delete p; } };
{
    std::unique_ptr p3(new Foo); // 使用 D 刪除
}

三、所有權轉移演示

std::unique_ptr p1(new Foo);
p1->bar(); // 使用

{
    std::unique_ptr p2(std::move(p1)); // 所有權移給 p2
    f(*p2);                                 // p2 可用
    p1 = std::move(p2);                     // 移回 p1
    // p2 現在為空
    p2->bar(); // UB!p2 為 nullptr
}
p1->bar(); // p1 再次有效

四、數組版所有權轉移

std::unique_ptr p1(new Foo[4]);
{
    std::unique_ptr p2(std::move(p1));
    f(p2[0]);
    p1 = std::move(p2);
}
p1[0].bar(); // OK

五、最佳實踐建議

  1. 工廠函數返回 unique_ptr:明確所有權歸屬,避免洩漏。
    std::unique_ptr createFoo() { return std::make_unique(); } (C++14 make_unique)。
  2. 避免在容器存裸指針:用 vector<unique_ptr> 管理多態對象。
  3. 自定義刪除器管理非 new 內存:fclose、CloseHandle、free、munmap 等。
    using FilePtr = unique_ptr; FilePtr fp(fopen("a.txt","r"), fclose);
  4. 不適用場景:多線程共享所有權 → 用 shared_ptr;需要弱引用打破循環 → 用 weak_ptr。

六、輸出對照(示例程序運行結果)

TestDestroy................
Foo::Foo
Foo::~Foo
Foo::Foo
Foo::Foo
Foo::Foo
Foo::Foo
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::Foo
D operator()
Foo::~Foo
TestOwner................
Foo::Foo
Foo::bar
f(const Foo&)
Foo::bar
destroying p2...
Foo::bar
Foo::~Foo
TestArrayOwner................
Foo::Foo
Foo::Foo
Foo::Foo
Foo::Foo
Foo::bar
f(const Foo&)
Foo::bar
destroying p2...
Foo::bar
Foo::~Foo
Foo::~Foo
Foo::~Foo
Foo::~Foo
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved