In the past whenever I needed to create an instance of a class I would use new to allocate it on the heap (except for stl classes, and math classes like vec3 and mat4).
Your default behavior should be:
If the lifespan of the object is consistent with a specific scope
ie easily determined at compile time
then it should be an automatic storage duration object (stack like)
If the lifespan of the object is defined at runtime and extends beyond the current scope
Then it should be a a dynamic storage duration object (heap like)
Note: All dynamic storage duration objects should have their lifespan controlled by wrapping them in a an appropriate RAII class. Usually this means: For single objects a smart pointer, while multiple objects end up in a container.
I hate to see things defines as stack Vs heap. As it does not convey the real semantics of the situation.
int x; // its on the stack
struct X
{
int x; // Is this a stack or heap object?
} // It depends on its parent.
// But in both cases it is an automatic storage duration object.
// In both cases the lifespan's are well defined.
// The first is defined by the scope it is declared within.
// The second is defined by the lifespan of its parent.
You should be thinking in terms of automatic/dynamic 'storage duration' objects. This conveys the correct semantics of the language.
Note there are two other types of variable thus making four different types of variable. automatic/dynamic/static/thread 'storage duration' objects.