Two languages could hardly be less alike than Java and C++ - the latter is not garbage collected and where destructors are called is completely predictable.
It is more deterministic in C++, but you can still call exit(). (which is even more straightforward than the refcount cycle)
in the specific case of shared_ptr, which are a small part of codebases, if they are even used - for instance an immense amount of C++ GUI programs use Qt which doesn't use shared_ptr-like ownership semantics but instead a tree-of-objects model which does not have this issue. In contrast in Java / C# any object that has a reference to another is at risk.
when I put some object on automatic storage in C++ I do so because I explicitely want it to go away when its scope is left (either by reaching } or through an exception)
But more that there is so much magic and abstractions that it is very hard for a dev to have a clear view of what is going on and what to expect. He has to 'guess' instead of just read the code. For that, I guess that it is similar to the current question of accountability of decisions made with deep learning algorithms.
As an example of my point, I would refer to the 'garbage collection' issues of a language like 'java'. GC will happen at a logically defined point like 'dirty mem > 100m' but from the developer point of view, his logic could suddenly lag unexpectedly in a middle of a simple operation because the GC was triggered by internal magic. It is very hard for a dev to be able to determine the memory usage at different points of the code and so have a certitude of when this operation could happen.