BTW: shiftOut also loops, it just loops the binary data, and not an array, so why its so different?
Lets compare the functions:
Shiftout: 1 byte temporary, 0 permanent
C595: 2 bytes temporary, 19 permanent. That's 1% of Memory on a Uno
Shiftout: 1 Byte is shiftet, no latch code so the function can be reused for any number of bytes without any change
C595: 16 bits are shifted. For more or less register, the library needs to be changed. Impossible to shift different data lengths on different pins.
Shiftout: No latch pin handling, easy data handling for packed bits. Data storage needs to be external. Easy to expand to int, long or strings, just call function repeatedly. Individual bit access needs handled externally with bitset/bitclear operations.
C595: Latch pin handling, internal stoarage, good access to individual pins. Handling of packed data horrible.
So one can easily see, that your library is mostly failing and the little added benefit is overshadowed by all the problems. If the good features of your class were to be implemented properly in a class, you should store your data internally as bytes, have your accessor function convert positions into bits and let internally the shiftOut function handle the shifting. That way you'd have exactly the same interface for your class with all the benefit of proven standard code and without any of the shortcomings. This would be the solution expected from an experienced software development. If you need an example how to achieve it, just let me know and I'll a sample for you.
You have to keep in mind that I come from Windows C++ and Assembly programming, not MC programming. So I tend to like things in a certain way.
My experience with developing Windows dates already back some 10 years and I haven't kept too much with it recently, I was more busy with scripting and application languages to earn my keep. But I find it sad that the Windows environment forces people these days to produce crappy code, as you imply.