C++ std::unique_ptr 用法與範例

本篇 ShengYu 介紹 C++ 的 std::unique_ptr 用法與範例,unique_ptr 跟 shared_ptr 用法一樣,只是他的指標不能共享,是唯一無二的,

  • 初始化用法
  • 函式傳遞 unique_ptr
  • 使用 move 轉移 unique_ptr 擁有權
  • 函式回傳 unique_ptr
  • unique_ptr 轉 shared_ptr

需要引入的標頭檔<memory>,編譯需要支援 C++11

初始化用法

使用 unique_ptr 初始化一個實體的範例如下,

1
unique_ptr<Student> s = make_unique<Student>();

要注意的是 make_unique 這個輔助函式是在 C++14 才加入的,所以如果編譯器未支援 C++14 而使用了 make_unique 會出現編譯錯誤唷!

不使用 make_unique 的寫法如下,但是比較不建議,因為會產生不連續記憶體區塊,比起一次分配連續記憶體區塊效能較差,

1
unique_ptr<Student> s = unique_ptr<Student>(new Student());

函式傳遞 unique_ptr

根據 unique_ptr 是唯一性的原則(不能被複製),所以在參數傳遞時不能使用傳值 call by value,而是要傳參考 call by reference,否則會編譯錯誤,範例如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
void func1(unique_ptr& a) {
// ...
}

void func2(unique_ptr b) {
// ...
}

int main() {
func1(a);
func2(b); // 編譯錯誤
return 0;
}

使用 move 轉移 unique_ptr 擁有權

前面提到說不能複製,但移動總可以了吧!可以的

1
2
3
4
5
6
7
//class Student;

unique_ptr<Student> s1 = make_unique<Student>();

unique_ptr<Student> s2 = s1; // 編譯錯誤

unique_ptr<Student> s3 = move(s1); // 移動到 s2, 之後不能去使用 s1

函式回傳 unique_ptr

前面提到 unique_ptr 不能複製,那函式要回傳 unique_ptr 要怎麼使用?
直接回傳 unique_ptr,如下範例,詳細討論可以看這篇

1
2
3
4
5
6
7
8
9
10
11
unique_ptr<Student> func1() {
auto s = make_unique<Student>();
// or
// unique_ptr<Student> s = unique_ptr<Student>(new Student());
return s;
}

int main() {
auto s = func1();
return 0;
}

unique_ptr 轉 shared_ptr

unique_ptr 轉 shared_ptr 有兩種方式,一種是

1
shared_ptr<Size> s = make_unique<Size>();

另一種是使用 move,

1
2
unique_ptr<Size> s1 = make_unique<Size>();
shared_ptr<Size> s2 = move(s1);

反過來 shared_ptr 轉 unique_ptr 則不行。

其他參考文章
std::unique_ptr - cppreference.com
https://en.cppreference.com/w/cpp/memory/unique_ptr
c++ - Returning unique_ptr from functions - Stack Overflow
https://stackoverflow.com/questions/4316727/returning-unique-ptr-from-functions

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
std::shared_ptr 用法與範例