Featured pattern: Weak reference
12345678910111213141516171819202122232425262728293031323334 | #include <memory>
class bar;
class foo
{
public:
foo(const std::shared_ptr<bar>& b)
: forward_reference{b}
{ }
private:
std::shared_ptr<bar> forward_reference;
};
class bar
{
public:
void set_back_reference(const std::weak_ptr<foo>& f)
{
this->back_reference = f;
}
void do_something()
{
std::shared_ptr<foo> shared_back_reference = this->back_reference.lock();
if (shared_back_reference) {
// Use *shared_back_reference
}
}
private:
std::weak_ptr<foo> back_reference;
}; |
Intent
Maintain a non-owning reference to a shared dynamically allocated object to break circular dependencies.
Description
The std::weak_ptr
type represents a non-owning reference to dynamically allocated object with shared ownership (std::shared_ptr
). As they do not contribute to the reference count of the managed object they refer to, the object...
All patterns
Algorithms
Copy a range of elements
Copy elements from a range to another range or container.
Count occurrences of value in a range
Count the number of occurrences of a particular value in a range of elements.
Classes
Copy-and-swap
Implement the assignment operator with strong exception safety.
Delegate behavior to derived classes
Delegate behavior to derived classes without incurring the cost of run-time polymorphism.
Lexicographic ordering
Implement a lexicographic ordering over class members.
Non-member non-friend interfaces
Reduce dependencies on internal class details and improve encapsulation.
The PIMPL idiom
Remove compilation dependencies on internal class implementations and improve compile times.
The rule of five
Safely and efficiently implement RAII to encapsulate the management of dynamically allocated resources.
The rule of zero
Utilise the value semantics of existing types to avoid having to implement custom copy and move operations.
Virtual constructor
Create a copy of an object through a pointer to its base type.
Concurrency
Pass values between threads
Use promises to communicate values between threads.
Containers
Check existence of a key
Check if a particular key is in an associative container.
Remove elements from a container
Use the erase-remove idiom to remove elements from a container.
Functions
Optional arguments
Allow argument values to be omitted when calling a function.
Return multiple values
Return multiple values of different types from a function.
Input streams
Read a line of values
Read a sequence of delimited values from a single line of an input stream into a standard container.
Validate multiple reads
Ensure that multiple stream reads are successful before using the extracted values.
Memory management
Shared ownership
Share ownership of a dynamically allocated object with another unit of code.
Unique ownership
Transfer unique ownership of a dynamically allocated object to another unit of code.
Use RAII types
Avoid manual memory management to improve safety and reduce bugs and memory leaks.
Weak reference
Maintain a non-owning reference to a shared dynamically allocated object to break circular dependencies.
Output streams
Write data in columns
Align data in columns when writing to an output stream.
Random number generation
Flip a biased coin
Generate a random boolean value according to a bernoulli distribution.
Unpredictable random numbers
Seed a random number engine with greater unpredictability.
Ranges
Range-based algorithms
Implement algorithms that can be applied to any generic range of elements.
Range iteration
Iterate over a range of elements without using iterators or indices.
Templates
Class template SFINAE
Conditionally instantiate a class template depending on the template arguments.
Function template SFINAE
Conditionally instantiate a function template depending on the template arguments.
Perfect forwarding
Forward arguments of one function to another as though the wrapped function had been called directly.
Time
Fixed time step
Block the execution of a thread until a fixed point in time.