The main practical difference is what happens when the mainwindow is destroyed while a subwindow still exists and is using the network service:
- If you use
unique_ptr
and pass raw pointers then you get undefined behavior. - If you use
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.