Having named constructors while avoiding their use as a method?

80 Views Asked by At

I really like the syntax of "named constructors," which I understand to be static methods that return the object hosting them? (I apologize if "named constructors" isn't the right term for this.) But I've accidentally called them as a member way too many times... I'm wondering if there's a way to possibly keep this syntax, while helping myself avoid this mistake?

class TextureDef {
public:
    TextureDef(){} // default value of 1x1x1, 2D, r8, etc
    static TextureDef as1D(uint32 xSize, TextureFormat::Type format = TextureFormat::rgba8, uint8 mipmapCount = 1);
    static TextureDef as2D(uint32 xSize, uint32 ySize, TextureFormat::Type format = TextureFormat::rgba8, uint8 mipmapCount = 1);
    static TextureDef as3D(uint32 xSize, uint32 ySize, uint32 zSize, TextureFormat::Type format = TextureFormat::rgba8, uint8 mipmapCount = 1);
    static TextureDef as1Darray(uint32 xSize, uint32 arrayCount, TextureFormat::Type format = TextureFormat::rgba8, uint8 mipmapCount = 1);     
    static TextureDef as2Darray(uint32 xSize, uint32 ySize, uint32 arrayCount, TextureFormat::Type format = TextureFormat::rgba8,uint8 mipmapCount = 1);        
    static TextureDef asBuffer(uint32 xSize, TextureFormat::Type format = TextureFormat::rgba8);    
    static TextureDef asRect(uint32 xSize, uint32 ySize, TextureFormat::Type format = TextureFormat::rgba8);        
    static TextureDef asCubemap(uint32 xySize, TextureFormat::Type format = TextureFormat::rgba8, uint8 mipmapCount = 1);       
    static TextureDef asCubemapArray(uint32 xySize, uint32 arrayCount, TextureFormat::Type format = TextureFormat::rgba8, uint8 mipmapCount = 1);
    static TextureDef as2DMS(uint32 xSize, uint32 ySize, TextureFormat::Type format = TextureFormat::rgba8, uint8 samples = 4);     
    static TextureDef as2DMSarray(uint32 xSize, uint32 ySize, uint32 arrayCount, TextureFormat::Type format = TextureFormat::rgba8, uint8 samples = 4); 

    ...
};

void usageExample(Canvas & canvas) {

    // this syntax feels really nice, 'cause I'm a loser who leans auto-complete
    canvas.allocTexture(TextureDef::as2D(100, 100));

    // BUT... I sometimes burn myself by accident...
    TextureDef def;
    def.as2D(100, 100);  // `def` is unaffected
    canvas.allocTexture(def); 
}

I've adopted a consistent naming convention for these kind of methods. static Point Point::asPolar(...); where as is always the first word. "As" if that would help.

I've also thought of making the default constructor be private? If that is the best way, I'm not sure though...

(As rationale for why I'm stubborn about a syntax that's so prone to pain, it's because... I often forget my own free-functions, and naming anything in the global namespace is a lot of pressure. Making a namespace for them feels weird too because I would want to name this namespace the same as the class? Having them in the class's namespace helps me out a lot.)

0

There are 0 best solutions below