A std::weak_ptr is a non-owning smart pointer that observes an object managed by a std::shared_ptr. It does not affect the reference count, meaning it does not extend the objectโs lifetime.
It is mainly used to break cyclic dependencies (e.g., two shared_ptrs referencing each other, creating a memory leak because neither gets destroyed).
#include <iostream>
#include <memory>
class Resource {
public:
Resource(int id) : id_(id) { std::cout << "Resource " << id_ << " acquired.\\n"; }
~Resource() { std::cout << "Resource " << id_ << " released.\\n"; }
void show() const { std::cout << "Resource ID: " << id_ << "\\n"; }
private:
int id_;
};
int main() {
std::shared_ptr<Resource> sp = std::make_shared<Resource>(100);
std::weak_ptr<Resource> wp = sp; // Create weak_ptr from shared_ptr
std::cout << "Use count (shared): " << sp.use_count() << "\\n"; // โ 1
if (!wp.expired()) {
std::shared_ptr<Resource> sp2 = wp.lock(); // Convert to shared_ptr
if (sp2) {
sp2->show(); // Safe to use
std::cout << "Use count (shared): " << sp.use_count() << "\\n"; // โ 2
}
}
sp.reset(); // Destroy the managed object
if (wp.expired()) {
std::cout << "Resource has expired.\\n";
}
return 0;
}
#include <iostream>
#include <memory>
struct B; // Forward declaration
struct A {
std::shared_ptr<B> b_ptr;
~A() { std::cout << "A destroyed\\n"; }
};
struct B {
std::weak_ptr<A> a_ptr; // weak_ptr avoids cycle
~B() { std::cout << "B destroyed\\n"; }
};
int main() {
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
a->b_ptr = b;
b->a_ptr = a; // weak_ptr avoids cyclic dependency
return 0;
}
If B::a_ptr were a shared_ptr, both a and b would never be destroyed due to the cyclic reference.