Skip to content
C++ Basics: Observe Lifetime with std::weak_ptr

C++ Basics: Observe Lifetime with std::weak_ptr

November 2, 2026

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 1

Run 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-demo

Observed output:

While owned: ready
After scope: expired

Read 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_directory

If the directory is not empty, inspect its remaining contents before removing anything else.

Acknowledgements

This post was created with assistance from AI.

Last updated on