在 C++ 中,智能指針是一種對象,它允許對原始指針進行更安全和更方便的操作。智能指針可以自動管理指向的對象的生命周期,當智能指針不再需要時,它會自動刪除所指向的對象。
C++ 中常見的智能指針有 unique_ptr
、shared_ptr
和 weak_ptr
。
unique_ptr
unique_ptr
是一種獨占所有權的智能指針,它保證同一時刻只有一個 unique_ptr
可以指向一個對象。當 unique_ptr
被銷毀時(例如離開其作用域),它所指向的對象也會被自動刪除。
示例代碼:
#include <iostream>
#include <memory>
struct Foo {
Foo() { std::cout << "Foo::Foo\n"; }
~Foo() { std::cout << "Foo::~Foo\n"; }
};
void func(std::unique_ptr<Foo> ptr) {
std::cout << "func: ptr.use_count() = " << ptr.use_count() << '\n';
}
int main() {
std::unique_ptr<Foo> ptr(new Foo);
std::cout << "ptr.use_count() = " << ptr.use_count() << '\n';
func(std::move(ptr));
std::cout << "ptr.use_count() = " << ptr.use_count() << '\n';
return 0;
}
輸出結果:
Foo::Foo
func: ptr.use_count() = 2
Foo::~Foo
func: ptr.use_count() = 1
Foo::~Foo
shared_ptr
shared_ptr
是一種共享所有權的智能指針,它允許多個 shared_ptr
對象共享同一個對象。shared_ptr
使用引用計數來跟蹤指向同一個對象的 shared_ptr
對象數量。當最后一個指向對象的 shared_ptr
被銷毀時,對象會被自動刪除。
示例代碼:
#include <iostream>
#include <memory>
struct Foo {
Foo() { std::cout << "Foo::Foo\n"; }
~Foo() { std::cout << "Foo::~Foo\n"; }
};
void func(std::shared_ptr<Foo> ptr) {
std::cout << "func: ptr.use_count() = " << ptr.use_count() << '\n';
}
int main() {
std::shared_ptr<Foo> ptr1(new Foo);
std::cout << "ptr1.use_count() = " << ptr1.use_count() << '\n';
{
std::shared_ptr<Foo> ptr2 = ptr1;
std::cout << "ptr1.use_count() = " << ptr1.use_count() << '\n';
std::cout << "ptr2.use_count() = " << ptr2.use_count() << '\n';
}
std::cout << "ptr1.use_count() = " << ptr1.use_count() << '\n';
func(ptr1);
std::cout << "ptr1.use_count() = " << ptr1.use_count() << '\n';
return 0;
}
輸出結果:
Foo::Foo
ptr1.use_count() = 1
func: ptr1.use_count() = 2
Foo::~Foo
func: ptr1.use_count() = 1
Foo::~Foo
weak_ptr
weak_ptr
是一種弱引用智能指針,它不擁有指向的對象,只是觀察對象。weak_ptr
可以用來避免 shared_ptr
之間的循環引用問題。weak_ptr
可以升級為 shared_ptr
,如果原 shared_ptr
仍然存在,則升級成功,否則升級為空 shared_ptr
。
示例代碼:
#include <iostream>
#include <memory>
struct Foo {
Foo() { std::cout << "Foo::Foo\n"; }
~Foo() { std::cout << "Foo::~Foo\n"; }
};
void func(std::weak_ptr<Foo> wp) {
if (auto sp = wp.lock()) {
std::cout << "func: sp.use_count() = " << sp.use_count() << '\n';
} else {
std::cout << "func: wp has expired\n";
}
}
int main() {
std::shared_ptr<Foo> ptr1(new Foo);
std::weak_ptr<Foo> wp = ptr1;
func(wp);
std::cout << "ptr1.use_count() = " << ptr1.use_count() << '\n';
return 0;
}
輸出結果:
Foo::Foo
func: sp.use_count() = 1
Foo::~Foo
ptr1.use_count() = 1