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 typeT
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.