It's a matter of semantics:
- smart pointer: you own (at least partly) the memory being pointed to, and as such are responsible for releasing it
- regular pointer: you are being given a handle to an object... or not (NULL)
For example:
class FooContainer { public: typedef std::vector<Foo> foos_t; foos_t::const_iterator fooById(int id) const; // natural right ? };
But you expose some implementation detail here, you could perfectly create your own iterator class... but iterator usually means incrementable etc... or use a pointer
class FooContainer { public: const Foo* fooById(int id) const; };
Possibly it will return NULL, which indicates a failure, or it will return a pointer to an object, for which you don't have to handle the memory.
Of course, you could also use a weak_ptr here (you get the expired method), however that would require using shared_ptr in the first place and you might not use them in your implementation.