I would like to point out a thing 1st then share some of my experience. Please be careful with saying Abstract Base Classes and Interfaces so freely alongside. ABCs are language concept and Interface is a design concept. Of course ABCs are very handy in implementing interfaces in c++
, however I do not think it is said anywhere (high credible source) that they are meant specifically for it. There are other ways to do it! Please take a read http://accu.org/index.php/journals/471.
That being said, to answer your question. In my experience as the rule of thumb you should always write code that you feel is designed well. If you think virtuals will cripple your performance, seriously do not bother unless you can prove it is more than 10% if you plan on managing your code. If it is one-shot, squeeze it all, code design does not matter.
Sadly one needs to learn how to analyze and profile applications, at a level that I would consider quite high, to properly re-design code. You should be able to tell if you need to reorganize branches, eliminate virtuals or memory management or find bottlenecks. I believe nowadays they are much more often hardware related. If you look through some SO c++
performance questions you will see that bottle necks lied in very strange places and only people who profiled code for cache misses or branch predictions were able to find causes.
I must say that, I had fallen victim to pre-mature optimizations, as well as under- and over- design. I tried to implement (heck, i did implement) clever things where they were not needed, and only complicated code and interface system to a point where it was not fun to extend my own programs. For the sake of like 5% speed-up I effectively encumbered process of testing to the point I had to spend a day to implement tests or test it manually after adding some new feature. I also went down to such thing as get_x(){ return x;};
was virtual
because it shared interface with something that had different memory management.
To sum up, for now my advice would be:
Write code that is well designed for current needs (and maybe immediate future). Do not try to over complicate it beforehand. It's just as bad as premature opitmizations. Personal experience.
When it is appropriate, then refactor and introduce templates.
Don't care about performance, unless you are sure you need. Learn to high-quality analyze your code. Then work on bottle necks.
Of course its probably twice as much work as getting everything right in the 1st place. In my case the problem is I miss the right
way 2 out of 3 times if not more :). I believe over time a good programmer is able to choose good approach beforehand more often.
On the templates vs ABCs for interfaces.
I think ABCs are more-programmer friendly and readable, however I would got for template polymorphism if I ran into something like:
...
virtual get_x() {return coords[0];};
virtual get_y() {return coords[1];};
virtual get_z() {return coords[2];};
...
void some_fancy_algorithm_that_work_on_coords(){
// for example calculate distances between every pair of instances
// that can provide `ICoords` interface
}
I template base polymorphism a half-decent compiler can eliminate implicit object casts and use referenced methods and properties directly. It is good to avoid virtuals and intermediate access, even though everything is wrapped in the code design.
auto
and if needed switch to templates, much simpler change.