Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
roth_stephan_clean_c20_sustainable_software_development_patt-1.pdf
Скачиваний:
25
Добавлен:
27.03.2023
Размер:
7.26 Mб
Скачать

Chapter 5 Advanced Concepts of Modern C++

private:

std::weak_ptr<A> myPointerToA;

}; // ...

Basically, circular dependencies are bad design in application code and should be avoided whenever possible. There might be a few exceptions in low-level libraries where circular dependencies cause no serious issues. But apart from that, you should follow the acyclic dependency principle, which is discussed in a dedicated section in Chapter 6.

Atomic Smart Pointers

As I mentioned briefly, the implementations of std::shared_ptr<T> and std::weak_ ptr<T> are thread-safe by design. But this only applies to the reference count block of the pointers, not to the resource that is managed and shared by them! std::shared_ptr<T> guarantees that counting up and down the reference counter, as well as deleting the managed resource if necessary, are atomic operations.

ATOMIC OPERATION

In computer science and software development, an atomic operation is a compound of single operations that can be seen as one undividable logical unit. This means that they can only be successful or fail as a whole. Atomic operations play an important role in database changes (so-called transaction safety), as well as in the implementation of locking mechanisms to avoid data races in parallel programming.

In contrast, these pointers cannot guarantee that the uses of the resources they manage are atomic, nor that non-const method calls (e.g., assigning a new resource) invoked on them are atomic (and thus thread-safe). The second problem is now solved by the two new partial specializations of std::atomic<T> introduced with C++20: std::atomic<std::shared_ptr<T>> and std::atomic<std::weak_ptr<U>> (both defined in the <memory> header). To prevent data races and undefined behavior in a concurrent environment with the standard smart pointers, atomic, smart pointer types should be used instead. However, be careful: You should always keep in mind that the managed resource is still not protected from data races even with these atomic pointers!

143