weak_ptr
用來搭配 shared_ptr,當 shared_ptr
實例用來建構 weak_ptr
實例或指定給 weak_ptr
時,動態配置資源的參考計數並不會增加。例如:
#include <iostream>
#include <memory>
using namespace std;
template<typename T>
struct Node {
Node(T v) : v(v) {}
~Node() {
cout << v << " deleted" << endl;
}
T v;
weak_ptr<Node<T>> pre;
weak_ptr<Node<T>> nxt;
};
weak_ptr<Node<int>> foo() {
auto sp = make_shared<Node<int>>(10);
weak_ptr<Node<int>> wp = sp;
cout << wp.expired() << endl; // 0
shared_ptr<Node<int>> sp2 = wp.lock();
cout << sp2->v << endl; // 10
return wp;
}
int main() {
weak_ptr<Node<int>> wp = foo();
cout << wp.expired() << endl; // 1
return 0;
}
在這個範例中,sp
動態配置的資源要不要刪除,與 wp
沒有關係,weak_ptr
指向的資源還有沒有效(是否被刪除),可以透過 expired
來得知,若要取得資源,可以透過 lock
方法,如果資源仍有效,就會傳回 shared_ptr
實例,否則傳回 nullptr
。
weak_ptr
用來搭配 shared_ptr
,應用場合之一是解決 shared_ptr
形成環狀的問題,例如底下的範例會因為 shared_ptr
形成環狀,使得最後各自的資源並沒有被刪除:
#include <iostream>
#include <memory>
using namespace std;
template<typename T>
struct Node {
Node(T v) : v(v) {}
~Node() {
cout << v << " deleted" << endl;
}
T v;
shared_ptr<Node<T>> pre;
shared_ptr<Node<T>> nxt;
};
int main() {
auto node1 = make_shared<Node<int>>(10);
auto node2 = make_shared<Node<int>>(20);
cout << node1.use_count() << endl // 1
<< node2.use_count() << endl; // 1
node1->nxt = node2;
node2->pre = node1;
cout << node1.use_count() << endl // 2
<< node2.use_count() << endl; // 2
return 0;
}
可以看到,shared_ptr
被指定給 shared_ptr
,會令參考計數增加,兩個 shared_ptr
實例各自被回收時,各自的參考計數都會是一而不是零,shared_ptr
各自的資源並不會被刪除,若是底下程式:
#include <iostream>
#include <memory>
using namespace std;
template<typename T>
struct Node {
Node(T v) : v(v) {}
~Node() {
cout << v << " deleted" << endl;
}
T v;
weak_ptr<Node<T>> pre;
weak_ptr<Node<T>> nxt;
};
int main() {
auto node1 = make_shared<Node<int>>(10);
auto node2 = make_shared<Node<int>>(20);
cout << node1.use_count() << endl // 1
<< node2.use_count() << endl; // 1
node1->nxt = node2;
node2->pre = node1;
cout << node1.use_count() << endl // 1
<< node2.use_count() << endl; // 1
return 0;
}
shared_ptr
被指定給 weak_ptr
,不會令參考計數增加,兩個 shared_ptr
實例各自被回收時,各自的參考計數都會是零,shared_ptr
各自的資源可以被刪除。