C++ Basics: Observe Lifetime with std::weak_ptr
Lock a weak pointer before access and detect when the last shared owner has disappeared.
Prepare a scratch directory
Tested on Linux x86_64 with GCC 14.2.0. Install a C++20-capable GCC compiler and its standard-library development files, with g++ on PATH. You also need Bash, a text editor, and mktemp, rm, and rmdir. No third-party library is required.
Keep the same terminal open. Stop if setup fails before saving the source:
start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1Run the example
Save this as weak-pointer-expiration-demo.cpp:
#include <iostream>
#include <memory>
#include <string>
int main()
{
std::weak_ptr<std::string> observer;
{
auto owner = std::make_shared<std::string>("ready");
observer = owner;
if (auto temporary_owner = observer.lock()) {
std::cout << "While owned: " << *temporary_owner << '\n';
}
}
if (auto temporary_owner = observer.lock()) {
std::cout << *temporary_owner << '\n';
} else {
std::cout << "After scope: expired\n";
}
}Compile and run it. The second command runs only after compilation succeeds:
g++ -std=c++20 -Wall -Wextra -Werror -pedantic weak-pointer-expiration-demo.cpp -o weak-pointer-expiration-demo &&
./weak-pointer-expiration-demoObserved output:
While owned: ready
After scope: expiredRead the result
A weak pointer observes shared ownership without extending the object lifetime. lock returns a shared pointer when the object is still alive. The temporary owner inside the if statement is gone before the outer owner leaves scope, so the final lock returns empty.
Apply it carefully
Prefer lock-and-test over checking expired and then trying to access the object separately. Another thread could release the last owner between separate operations. A weak back-reference can prevent a shared-ownership cycle, but this example demonstrates expiration rather than building a cycle. A live shared pointer protects lifetime, not unsynchronized mutation of the pointed-to object.
The C++ working draft documents the relevant behavior. This example uses C++20 features, not newer additions shown elsewhere in the current draft.
Clean up
Remove only the source and executable created here, then remove the empty practice directory:
rm -- weak-pointer-expiration-demo.cpp weak-pointer-expiration-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directoryIf the directory is not empty, inspect its remaining contents before removing anything else.
Acknowledgements
This post was created with assistance from AI.