Weak pointers

libbase implements Chromium’s weak pointers [1] to allow writing safer code. This module consists of two classes:

  • base::WeakPtr<T>

    This class represents a weak pointer to an object of type T which can be used to check if this object is still alive (or if the weak pointer itself is still valid, to be precise [2]) and if it is, to access it in a safe manner.

  • base::WeakPtrFactory<T>

    This class provides a functionality of creation of base::WeakPtr<T> objects and managing whether they are still valid and can be used.

    Note

    A single instance of base::WeakPtrFactory<T> refers only to one object of type T throughout its lifetime.

The notable difference between the base::WeakPtr<T> class and the standard std::weak_ptr<T> class is that base::WeakPtr<T> objects do not extend the lifetime of the pointed-to object and therefore can be used to point to objects allocated on the stack. The user is required to check if the object is still accessible (with base::WeakPtr::operator bool()) before accessing the pointed-to object - which can be done with any of these functions:

A base::WeakPtr<T> objects are created from a base::WeakPtrFactory<T> object. When constructing the factory, it requires a pointer to the object to which all the base::WeakPtr<T> objects created from it will point to. Then, all created base::WeakPtr<T> objects will be considered valid until either the factory is destroyed or a call to the base::WeakPtrFactory::InvalidateWeakPtrs() member function is made.

Note

It is still possible to create new and valid base::WeakPtr<T> objects from base::WeakPtrFactory<T> on which the base::WeakPtrFactory::InvalidateWeakPtrs() member function was called. The invalidation affects only existing weak pointers.

Important

The base::WeakPtrFactory<T> is often the last member in the class it generates weak pointers to. This ensures that all existing weak pointers will be invalidated before any other member variable from that class will be destroyed.

Once a first weak pointer from a given factory is dereferenced (tested or used to access the pointed-to object), both the factory and all the existing weak pointers created by it become bound to the sequence on which it happend and from that point in time can only be dereferenced or invalidated on that sequence.

Caution

While it is perfectly safe to copy and pass base::WeakPtr<T> objects across different threads and sequences, they can be used only on the sequence on which they were bound!

This is required to ensure that the pointed-to object is not destroyed (on a different thread) between checking if it is still alive and actually accessing it.

Caution

If all weak pointers created by a given factory would be destroyed, the factory automatically unbinds itself from the bounded sequence and newly created base::WeakPtr<T> can be used on different sequences.

Example - base::WeakPtr<T> and base::WeakPtrFactory<T> usage

 1 #include <iostream>
 2 
 3 #include "base/memory/weak_ptr.h"
 4 
 5 class Foo {
 6  public:
 7   void Bar() {
 8     std::cout << "Hello World!" << std::endl;
 9   }
10 
11   base::WeakPtr<Foo> GetWeakPtr() const {
12     return weak_factory_.GetWeakPtr();
13   }
14 
15  private:
16   base::WeakPtrFactory<Foo> weak_factory_{this};
17 };
18 
19 int main() {
20   std::unique_ptr<Foo> foo = std::make_unique<Foo>();
21   base::WeakPtr<Foo> weak_foo = foo->GetWeakPtr();
22 
23   CHECK(weak_foo);
24   weak_foo->Bar();  // prints "Hello World!"
25 
26   foo.reset();
27   CHECK(!weak_foo);
28   // must NOT use `weak_foo` to try to access the pointed-to object anymore
29 
30   return 0;
31 }

See also

Check Callbacks page to see how base::WeakPtr<T> objects can be used to write safer code with callbacks or to create cancelable callbacks.