Because shared_ptr (and also unique_ptr) nudges you towards keeping each object in its own heap allocation, and that quickly gets inefficient with large number of objects. E.g. a handful of large objects managed through shared_ptr is usually fine, but managing many tiny C++ object individually through smart pointers usually isn't. Instead store large groups of objects of the same type and similar lifetime by value in a std::vector (and then maybe put that std::vector behind a smart pointer).
Also if you lean in too much on shared/unique pointers for large amounts of tiny objects you'll most likely end up in a situation where Java-style garbage collection would be more efficient.
E.g. manual or semi-manual memory management is mostly about controlling the overall memory layout of your application's data to improve throughput, reducing the number of individual heap allocations is just a useful side effect.
Comments
Because shared_ptr (and also unique_ptr) nudges you towards keeping each object in its own heap allocation, and that quickly gets inefficient with large number of objects. E.g. a handful of large objects managed through shared_ptr is usually fine, but managing many tiny C++ object individually through smart pointers usually isn't. Instead store large groups of objects of the same type and similar lifetime by value in a std::vector (and then maybe put that std::vector behind a smart pointer).
Also if you lean in too much on shared/unique pointers for large amounts of tiny objects you'll most likely end up in a situation where Java-style garbage collection would be more efficient.
E.g. manual or semi-manual memory management is mostly about controlling the overall memory layout of your application's data to improve throughput, reducing the number of individual heap allocations is just a useful side effect.