Resource Acquisition is Initialization
https://en.cppreference.com/w/cpp/language/raii
RAII can be summarized as follows:
- encapsulate each resource into a class, where
- the constructor acquires the resource and establishes all class invariants or throws an exception if that cannot be done,
- the destructor releases the resource and never throws exceptions;
- always use the resource via an instance of a RAII-class that either
- has automatic storage duration or temporary lifetime itself, or
- has lifetime that is bounded by the lifetime of an automatic or temporary object
ex:
std::mutex m; void bad() { m.lock(); // acquire the mutex f(); // if f() throws an exception, the mutex is never released if(!everything_ok()) return; // early return, the mutex is never released m.unlock(); // if bad() reaches this statement, the mutex is released } void good() { std::lock_guard<std::mutex> lk(m); // RAII class: mutex acquisition is initialization f(); // if f() throws an exception, the mutex is released if(!everything_ok()) return; // early return, the mutex is released } // if good() returns normally, the mutex is released
RAII:
- std::string, std::vector, containers
- std::unique_ptr and std::shared_ptr to manage dynamically-allocated memory or, with a user-provided deleter, any resource represented by a plain pointer;
- std::lock_guard, std::unique_lock, std::shared_lock to manage mutexes.
cycle reference:
https://www.learncpp.com/cpp-tutorial/circular-dependency-issues-with-stdshared_ptr-and-stdweak_ptr/
example :
this program doesn’t execute as expected: -> they are not distrcted in the end
Lucy created Ricky created Lucy is now partnered with Ricky
With weak_ptr:
This code behaves properly:
Lucy created Ricky created Lucy is now partnered with Ricky Ricky destroyed Lucy destroyed
The downside of std::weak_ptr is that std::weak_ptr are not directly usable (they have no operator->). To use a std::weak_ptr, you must first convert it into a std::shared_ptr. Then you can use the std::shared_ptr. To convert a std::weak_ptr into a std::shared_ptr, you can use the lock() member function
std::weak_ptr is a smart pointer that holds a non-owning ("weak") reference to an object that is managed by std::shared_ptr. It must be converted to std::shared_ptr in order to access the referenced object.https://en.cppreference.com/w/cpp/memory/weak_ptr
#include <iostream> #include <memory> std::weak_ptr<int> gw; void observe() { std::cout << "gw.use_count() == " << gw.use_count() << "; "; // we have to make a copy of shared pointer before usage: if (std::shared_ptr<int> spt = gw.lock()) { std::cout << "*spt == " << *spt << '\n'; } else { std::cout << "gw is expired\n"; } } int main() { { auto sp = std::make_shared<int>(42); gw = sp; observe(); } observe(); }
No comments:
Post a Comment