In an ideal world, all owning pointers are smart pointers, and raw non-owning pointers are only used when NULL is considered a potentially valid value. If it is indeed true that
specificObject will always be within
objects, then at least in theory it should be possible to make
specificObject be an
Object reference, thereby allowing the compiler to enforce that it always has a non-NULL value for its entire lifetime.
In a less than ideal world, it might not be feasible or even possible to initialize
specificObject to point to a member of
objects, depending on how exactly
specificObject is determined and whether that logic can reasonably be
constexpr'd. Then the question comes down to whatever the lifetimes of all the
objects are. If you know that they will all continue to exist at least as long as
specificObjects does, then a non-owning raw pointer is perfectly safe. I suspect this is the most typical situation.
In a very non-ideal world, it may be possible for
objects to gain and lose any of its members at any time, so you need to account for the possibility that
specificObject gets invalidated while your program is still trying to do stuff with it. In this case,
weak_ptr is the tool of choice, as it's specifically designed for situations where you don't know when the object's lifetime might end, yet you don't want to needlessly prolong it. Of course, that would require changing all your
shared_ptrs, and unsurprisingly it is the least intuitive of the smart pointers, which is why I'm mentioning this option last.