in the mainwindow of my QT app, I use a std::shared_ptr
to hold a pointer to an instance of my network service which manages all the connections to multiple clients. Now, I have to pass this pointer to multiple sub windows so that they can communicate with the clients.
Do i better use a std::shared_ptr
member variable in the main- and sub-windows and pass copy it when creating the subwindows, or is it better to use a std::unique_ptr
and pass a raw pointer to the sub Windows, as the mainwindow will outlive the subwindows anyway?
Thanks a lot!
In short, you can easily and efficiently convert a std::unique_ptr to std::shared_ptr but you cannot convert std::shared_ptr to std::unique_ptr .
shared_ptr is also helpful in C++ Standard Library containers when you're using algorithms that copy elements. You can wrap elements in a shared_ptr , and then copy it into other containers with the understanding that the underlying memory is valid as long as you need it, and no longer.
In short: Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.
The only difference between weak_ptr and shared_ptr is that the weak_ptr allows the reference counter object to be kept after the actual object was freed. As a result, if you keep a lot of shared_ptr in a std::set the actual objects will occupy a lot of memory if they are big enough.
The main practical difference is what happens when the mainwindow is destroyed while a subwindow still exists and is using the network service:
unique_ptr
and pass raw pointers then you get undefined behavior.shared_ptr
then the network service remains until all subwindows are destroyed.Now, if this condition is impossible by design then the undefined behavior is not inherently a problem. If the condition happens anyway due to a bug then it might help you to detect the bug if the network service is destroyed along with the main window, which would happen if you use unique_ptr
. Using unique_ptr
expresses that the mainwindow is the only thing that owns the network service, the others merely use it as directed by the mainwindow.
On the other hand, if you later change the design and want to make the condition legal, or if you want to use the subwindows in a different way that means there's no single network service object that they all use and that outlives them all, then it will be easier if you used shared_ptr
from the start. Using shared_ptr
expresses that all the windows share ownership of the network service.
I don't think it's possible to say in general whether you should try to make your code continue working in the face of "impossible conditions". In this case it's very cheap to do so (shared_ptr
is more expensive to copy than a raw pointer, of course, but cheap compared with creating a subwindow, and the code is structured the same either way). It can be useful to have the flexibility to make the "impossible condition" happen under certain circumstances, for example when unit testing the subwindow code. So probably use shared_ptr
for flexibility. If enforcing the lifetime constraint is a big deal for other reasons then you might not want any flexibility, in which case avoid writing code that will only ever hide bugs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With