The biggest argument against this that I can see is having to create a shape in order to create a sprite, and how managing an additional asset for every sprite that would annoy some people. You could make the default behaviour exactly the same as it is now, that is that sprites use rectangular shapes, by using a C++ feature called implicit conversion.
It all depends if the sprite owns the shape or not. If it does own the shape then you don't need an extra asset. (That's why I've been trying to say for a while but apparently failed to do so.)
Let's assume a sprite has its own shape. Then, by default, a sprite creates a rectangle shape. If told otherwise (e.g. with an explicit shape as constructor parameter or through factory methods) then it will copy this shape for its own usage. In both cases we don't have to keep track of this shape ourselves.
On the other hand, if it does *not* own the shape then we need to keep it alive long enough, like the texture. But I think it doesn't make sense to go that way: a shape is not that heavy (unlike the texture) and don't live on the GPU (also unlike the texture) so we can copy it a few times without trouble.
Oh yes I was agreeing with you.
I'm just saying that you have people who want to be able to make a sprite without bothering with shapes, and you have people that do want to bother with it.
Most people would implement your idea by setting the shape to be the last argument given in the constructor for the sprite class, and then giving it a default value equal to an arbitrary rectangle like a unit square. (ugly because we are stuck with a default size for the rectangle)
Or they would provide a a "shape selector" parameter (ugly because we are stuck with a "default" version, like a unit circle or unit rectangle)
Or they would make it so that sprite is unusable even after it is constructed until a factor method is used to set the shape (very bad implementation imho).
All of those implementations have things wrong with them that people could argue over.
What I'm saying is you can get around that with a nifty feature of C++ that allows you to just specify the argument
in the constructor of the sprite to be of the same type of the argument that constructs the shape-- but only if the shape can be built from one single argument. And whats nifty about it is you don't have to write any code. C++ just says "Oh gee I don't know how to build a sprite out of a vec2d or a float, but I know how to build it out of a shape, and I know how to build a circle out of a float and I know how to build a rectangle out of a vec2d, and circles and rectangles are both shapes, so I'll just use the right one."
Furthermore the sprite can have multiple arguments. It will substitute the right argument in the right place. You could write in the definition of sprite that it should take an argument shape, an argument color, and an argument position, and you automatically get atleast 2 constructors out of that "magically". Namely, the one that happens if I provide a float instead of a shape, and it gets turned into a circle, and the one that happens when I provide a vec2d instead of a shape, and it gets turned into a rectangle.
In other words there is no need to have a single "default shape". With this we get a default rectangle and a default circle (and a default w/e, one for each shape that can be built from a single unique parameter) and not only that, we don't have to settle for a "unit" rectangle or "unit" circle or whatever. We can specify the dimensions at the constructor and it will know what we meant, because there is no ambiguity. And it costs us nothing because we don't have to write more constructor code.