Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ standard practice: virtual interface classes vs. templates

I have to make a decision regarding generalization vs polymorphism.

Well the scenario is standard: I want to make my monolithic interdependent code to be more modular, clean and extensible. It is still in a stage where the change of design principle is doable, and, as I look at it, highly desirable.

Will I introduce purely virtual base classes (interfaces) or templates?

I am aware of the basics regarding the template option: less indirection, better performance, more compiling but no late binding, and so on.

The stl does not use much (or none?) inheritance, and boost doesn't either. But I think those are aimed to be really small basic tools that are used every 2 lines of code by the programmer.

I consider the inheritance and late binding approach to be more sensible for plug-in style of big pieces of code and functionality that should be interchangeable, updateable etc. after deployment or even during runtime.

Well my scenario lies somewhat inbetween.

I dont need to exchange pieces of code on the fly at runtime, compile time is fine. Usually it is also a very central and frequently used piece of functionality, it is not logically seperatable into big blocks.

This lets me tend somewhat to the template solution. To me it also looks somewhat cleaner.

Are there any big bad implications, are interfaces still THE way to go? When are they not? Which complies more with standard c++ style?

I know this is bordering on subjective, but I am really interested in some experiences. I don't own a copy of Scott Meyers effective C++ so I set my hopes on you guys :)

like image 904
AndreasT Avatar asked Jul 22 '09 15:07

AndreasT


2 Answers

You're basically right, dynamic polymorphism (inheritance, virtuals) is generally the right choice when the type should be allowed to change at runtime (for example in plugin architectures). Static polymorphism (templates) is a better choice if the type should only change at compile-time.

The only potential downsides to templates are that 1) they generally have to be defined in the headers (which means more code gets #included), and this often leads to slower compile-times.

But design-wise, I can't see any problems in using templates when possible.

Which complies more with standard c++ style?

Depends on what "standard C++ style" is. The C++ standard library uses a bit of everything. The STL uses templates for everything, the slightly older IOStreams library uses inheritance and virtual functions, and the library functions inherited from C uses neither, of course.

These days, templates are by far the most popular choice though, and I'd have to say that is the most "standard" approach.

like image 175
jalf Avatar answered Sep 25 '22 01:09

jalf


Properties of classic object-oriented polymorphism:

  • objects are bound at run-time; this is more flexible, but also consumes more resources (CPU) at run-time
  • strong typing brings somewhat more type safety, but the need to dynamic_cast (and its potential to blow up into a customer's face) might easily compensate for that
  • probably more widely known and understood, but "classical" deep inheritance hierarchies seem horrendous to me

Properties of compile-time polymorphism by template:

  • compile-time binding allows more aggressive optimizations, but prevents run-time flexibility
  • duck-typing might seem more awkward, but failures are usually compile-time failures
  • can sometimes be harder to read and understand; without concepts, compiler diagnostics might sometimes become enraging

Note that there is no need to decide for either one. You can freely mix and mingle both of them (and many other idioms and paradigms). Often, this leads to very impressive (and expressive) code. (See, for example, things like type erasure.) To get an idea what's possible through clever mixing of paradigms, you might want to browse through Alexandrescu's "Modern C++ Design".

like image 41
sbi Avatar answered Sep 25 '22 01:09

sbi