Search code examples
c++classvisual-c++abstractradix

Large abstract base classes


I'm writing a large abstract base class with 30 something purely virtual methods*.

Finding all the functions to implement in a base class in the implementation classes is a little tedious, mostly because MSVC++ does not tell you which function you failed to implement with compiler error "Cannot construct abstract class"

So, I'm wondering is my large abstract base class a bad idea, or should I split it up into several interfaces, or is there a compiler warning I can activate that'll tell me WHICH method I failed to provide an implementation for.. or is this just a part of coding with abstract classes and I should get used to it.

*What it does is provide a layer of common functionality between a few different rendering subsystems.


Solution

  • There's no obvious correct answer to this question. Deciding whether to factor apart the base class into multiple abstract base classes should probably be a decision you make based on whether or not the base class logically represents several different concepts, rather than on poor compiler error messages. If the only reason you'd do this is for the compiler error messages, you might want to check and see if you can upgrade the compiler or if there's some other reason to do this. Most modern compilers should provide very nice, detailed errors about this.

    Splitting the interface into pieces may be a good idea if your design suggests that you might actually want to have multiple different classes that implement just small pieces of the base class. If you expect to do this, it may be advantageous to factor the interface apart. You will see some added complexity from this, however. For example, if you have a pointer of one interface type to an object implementing multiple interfaces, you may have to do some sort of cross-cast to obtain the correct type, or you may have to introduce a new abstract class that represents something inheriting from all the different interface types. Multiple inheritance with interface classes might also lead to some name collisions, though this typically isn't a problem if the interfaces are designed correctly.

    In short, I'd strongly suggest not doing this for the compiler error reason, but if you think it's a good design decision then by all means go for it. Compilers are good enough these days that you rarely (but not never) need to build your design around them.