No, they are not the most efficient way to access resources. The same Sean Middleditch who gave you an answer wrote an article "Dangers of std::shared_ptr" against using shared_ptr about one year later. You might consider using handles again. As he wrote himself:
Game engines have long supported this kind of borrowed reference using things like unique ID handles. Instead of storing a pointer (smart or otherwise) to an object, store a numeric ID instead (possibly wrapped in a templated type to ensure type safety).
Please review the section Efficiency in his article for more explanations on how to be much more efficient when using handles in contrast to shared_ptr.
For more advantages of IDs you can read the short Entity Component System Pattern article.