Polymorphism in C++ can only be correct on pointers and references (which are pointers internally).
Stack-allocated objects and polymorphism only combine if the object is initialized as its true type and a pointer or reference to it is handed out. Obviously, this can create object lifetime issues if the pointer or reference escapes the lifetime of the stack frame containing the object.
What does your explanation have to do with the fact that C++ can express by-value returns of complex objects?