When to prefer templated policy based design over non-templated inheritance based design - c++

I am trying to understand the real requirement of the usage of templates for policy based design. Going through the new templated designs in C++ I found that policy based class design is a highly suggested way of design which allows you to 'plug-in' different behaviors from policy classes. A minimal example is the following (a shortened version of the wiki):
template <typename LanguagePolicy>
class HelloWorld : private LanguagePolicy
{
using LanguagePolicy::message;
public:
// Behaviour method
void run() const
{
// policy methods
cout << message();
}
};
class LanguagePolicyA
{
protected:
std::string message() const
{
return "Hello, World!";
}
};
//usage
HelloWorld<LanguagePolicyA> hello_worlda;
hello_worlda.run(); // prints "Hello, World!"
A quick analysis shows that just to get different plugable methods message() we are inheriting from a templated type whose definition can be provided by anyone (and identified at compile time).
But the same level of abstraction (and configurable methods) can be achieved without using a templated code and by the simple old school run time polymorphism as shown below.
class HelloWorld
{
LanguagePolicy *lp; //list of all plugable class
public:
HelloWorld(LanguagePolicy *lpn) {
lp = lpn;
}
// Behaviour method
void run() const
{
// policy methods
cout << lp->message();
}
};
class LanguagePolicy
{
protected:
virtual std::string message() const;
};
class LanguagePolicyA: LanguagePolicy
{
protected:
std::string message() const
{
return "Hello, World!";
}
};
//usage
HelloWorld helloworld(new LanguagePolicyA);
helloworld.run();
Functionality and level of abstraction wise I don't see much of a difference in the two approach (even though the second approach has few extra lines of code for LanguagePolicy, I think it is needed for the other users to know the interface; otherwise understanding LanguagePolicy depends upon the documentation). But I do think the later to be 'clean' (coming from someone who has not used template much). This is because personally in my opinion non-templated classes are cleaner to look at and understand. An extremely good example is the popular library VTK (Visualization Tool Kit) which solves many different problems using the second approach. Even though there are not extensive documentations of VTK, most of us - its users, can just have a look into its class diagrams (sometimes they are quite big) and deduce behaviors of classes; and develop highly configurable and complicated pipelines in our application (can't imaging VTK to be template based :)). The opposite is libraries like STL/BOOST which I don't think is possible for anyone to be able to identify the working of the classes without the use of extensive documentation.
So my question is, is the template based policy design really superior (only in this scenario of policy based design) than virtual inheritance based? If so, when and why?

Both are valid ways of structuring, it actually depends on the requirements. E.g.
Runtime vs compile time polymorphism.
When do you want/can/have to achieve polymorphism ?
Performance overhead of virtual calls
Templates generate code that has no indirections
The actual usage of the class.
When you have to store heterogenous collections, a base class is needed, so you have to use inheritance.
A very good book on policy-based design (a bit dated but good nevertheless) is Modern C++ Design

Depends on the situation I guess... A possible downside of using templates is that the type should be known at compile-time:
HelloWorld<English> hw; // English is plugged at compile-time
In your second example, where you're using a pointer-to-base, this pointer might point to a variety of derived classes. What exactly it points to is not required to be known at compile-time and can therefore be determined by (user-)input at runtime. A possible down-side of this approach is virtual call overhead. In some applications, and on some platforms, this might be unwanted.

Related

C++ hide template idiom from compile-time polymorphism

I'm writing a C++ hardware abstraction layer (HAL), which needs to be as fast as possible.
Polymorphism offers the best API, but Virtual Table lookups really kill the speed of the code.
This lead me to using templates in conjunction with policies to get compile-time polymorphism. But because templates with different arguments get instantiated as completely different types, I can not use them interchangeably in function calls unless the function is a template as well.
However, I dont want to force the user of my HAL library to write all function as templates because I have used templates.
For illustration purposes, suppose this is my HAL:
template<typename T_POLICY>
class I2CManager {
public:
void send(uint8_t data) {
T_POLICY::send(data);
++sent_data;
}
private:
int sent_data; // Just to illustrate that I2CManager has state
};
class I2C1 {
static void send(uint8_t data) { /* Run some code here */ }
};
class I2C2 {
static void send(uint8_t data) { /* Run other code here */ }
};
// OTHER HW
template<typename T_POLICY>
class UARTManager { ··· };
class UART1 { ··· };
class UART2 { ··· };
template<typename T_POLICY>
class TIMERManager { ··· };
class TIMER1A { ··· };
class TIMER1B { ··· };
This works and I can now create a I2CManager with different policies, such as follows. I can even have several I2CManagers running with different policies at the same time.
I2CManager<I2C1> i2c1;
I2CManager<I2C2> i2c2;
i2c1.send(0x11); // This works
i2c2.send(0x11); // This also works
Now, i2c1 and i2c2 have the same public methods, yet they are not interchangeable. Consequently, the user of my HAL library is forced to use templates as well.
// THIS DOES NOT WORK
void foo(I2CManager m) { m.send(0x11); }
foo(my_manager_1);
// BUT THIS WORKS
template<typename T>
void foo(I2CManager<T> m) { m.send(0x11); }
foo(i2c1);
Can I somehow get compile-time polymorphism but allow the end-user to treat it as if it was normal polymorphism? I don't care if the inner code in my library gets ugly or difficult to read for the sake of speed, but the API has to be as simple and intuitive as possible.
Actually, I want foo() to be specialized (and replicated in code) for the different parameters as if it was a template, but I don't want the user of my library to notice it is a template function. Altought alternatives to templates are also welcome.
I don't know if this is even possible, but I have read something about concepts which will appear in the next C++ standard. I want compile-time polymorphism, but as userfrliendly as runtime polymorhism.
Considerations:
Because I'm interfacing HW, each instantiation of my HWManagers with
different policies will be unique (i.e. There is only one
HWManager instance, and one HWManager instance,
and may or may not exist simultaneously).
All instances are created by the library as global variables, and are
not heapable.
All policy methods are extremely short, so having multiple unique
instances due to templates is preferable to Virtual Tables for the
sake of execution speed.
Code size does not matter (its for embedded systems), but RAM usage
and execution speed does. I need as much as possible to be solved
during compile time. Again, I'm willing to have a over-bloated
executable for the sake of avoiding run-time resolutions.
Only up to C++03 supported
Code example edited
All instances are created by the library as global variables, and are not heapable.
You mean something like this, right?
static HWManager<DrierPolicy> drierManager;
static HWManager<FridgePolicy> fridgeManager;
Then, what wrong with letting the user know about them and allow her/him to use those directly like:
drierManager.doStuff();
fridgeManager.doStuff();
And then...
Because I'm interfacing HW, each instantiation of my HWManagers with different policies will be unique
Then why implement the doStuff method as instance ones? Aren't some static methods good enough?
(those are questions, not critiques. Yes, I know, this is hardly an answer - it may be one though - but I needed the extra formatting that the comments do not provide)

Data abstraction that really allows isolating implementation from the user in C++

I hesitate to ask this question, because it's deceitfully simple one. Except I fail to see a solution.
I recently made an attempt to write a simple program that would be somewhat oblivious to what engine renders its UI.
Everything looks great on paper, but in fact, theory did not get me far.
Assume my tool cares to have an IWindow with IContainer that hosts an ILabel and IButton. That's 4 UI elements. Abstacting each one of these is a trivial task. I can create each of these elements with Qt, Gtk, motif - you name it.
I understand that in order for implementation (say, QtWindow with QtContainer) to work, the abstraction (IWindow along with IContainer) have to work, too: IWindow needs to be able to accept IContainer as its child: That requires either that
I can add any of the UI elements to container, or
all the UI elements inherit from a single parent
That is theory which perfectly solves the abstraction issue. Practice (or implementation) is a whole other story. In order to make implementation to work along with abstraction - the way I see it I can either
pollute the abstraction with ugly calls exposing the implementation (or giving hints about it) - killing the concept of abstraction, or
add casting from the abstraction to something that the implementation understands (dynamic_cast<>()).
add a global map pool of ISomething instances to UI specific elements (map<IElement*, QtElement*>()) which would be somewhat like casting, except done by myself.
All of these look ugly. I fail to see other alternatives here - is this where data abstraction concept actually fails? Is casting the only alternative here?
Edit
I have spent some time trying to come up with optimal solution and it seems that this is something that just can't be simply done with C++. Not without casting, and not with templates as they are.
The solution that I eventually came up with (after messing a lot with interfaces and how these are defined) looks as follows:
1. There needs to be a parametrized base interface that defines the calls
The base interface (let's call it TContainerBase for Containers and TElementBase for elements) specifies methods that are expected to be implemented by containers or elements. That part is simple.
The definition would need to look something along these lines:
template <typename Parent>
class TElementBase : public Parent {
virtual void DoSomething() = 0;
};
template <typename Parent>
class TContainerBase : public Parent {
virtual void AddElement(TElementBase<Parent>* element) = 0;
};
2. There needs to be a template that specifies inheritance.
That is where the first stage of separation (engine vs ui) comes. At this point it just wouldn't matter what type of backend is driving the rendering. And here's the interesting part: as I think about it, the only language successfully implementing this is Java. The template would have to look something along these lines:
General:
template<typename Engine>
class TContainer : public TContainerBase<Parent> {
void AddElement(TElementBase<Parent>* element) {
// ...
}
};
template<typename Engine>
class TElement : public TElementBase<Parent> {
void DoSomething() {
// ...
}
};
3. UI needs to be able to accept just TContainers or TElements
that is, it would have to ignore what these elements derive from. That's the second stage of separation; after all everything it cares about is the TElementBase and TContainerBase interfaces. In Java that has been solved with introduction of question mark. In my case, I could simply use in my UI:
TContainer<?> some_container;
TElement<?> some_element;
container.AddElement(&element);
There's no issues with virtual function calls in vtable, as they are exactly where the compiler would expect them to be. The only issue would be here ensuring that the template parameters are same in both cases. Assuming the backend is a single library - that would work just fine.
The three above steps would allow me to write my code disregarding backend entirely (and safely), while backends could implement just about anything there was a need for.
I tried this approach and it turns to be pretty sane. The only limitation was the compiler. Instantiating class and casting them back and forth here is counter-intuitive, but, unfortunately, necessary, mostly because with template inheritance you can't extract just the base class itself, that is, you can't say any of:
class IContainerBase {};
template <typename Parent>
class TContainerBase : public (IContainerBase : public Parent) {}
nor
class IContainerBase {};
template <typename Parent>
typedef class IContainerBase : public Parent TContainerBase;
(note that in all the above solutions it feels perfectly natural and sane just to rely on TElementBase and TContainerBase - and the generated code works perfectly fine if you cast TElementBase<Foo> to TElementBase<Bar> - so it's just language limitation).
Anyway, these final statements (typedef of class A inheriting from B and class X having base class A inheriting from B) are just rubbish in C++ (and would make the language harder than it already is), hence the only way out is to follow one of the supplied solutions, which I'm very grateful for.
Thank you for all help.
You're trying to use Object Orientation here. OO has a particular method of achieving generic code: by type erasure. The IWindow base class interface erases the exact type, which in your example would be a QtWindow. In C++ you can get back some erased type information via RTTI, i.e. dynamic_cast.
However, in C++ you can also use templates. Don't implement IWindow and QtWindow, but implement Window<Qt>. This allows you to state that Container<Foo> accepts a Window<Foo> for any possible Foo window library. The compiler will enforce this.
If I understand your question correctly, this is the kind of situation the Abstract Factory Pattern is intended to address.
The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes. In normal usage, the client software creates a concrete implementation of the abstract factory and then uses the generic interface of the factory to create the concrete objects that are part of the theme. The client doesn't know (or care) which concrete objects it gets from each of these internal factories, since it uses only the generic interfaces of their products. This pattern separates the details of implementation of a set of objects from their general usage and relies on object composition, as object creation is implemented in methods exposed in the factory interface.
Creating a wrapper capable of abstracting libraries like Qt and Gtk doesn't seems a trivial tasks to me. But talking more generally about your design problem, maybe you could use templates to do the mapping between the abstract interface and a specific implementation. For example:
Abstract interface IWidget.h
template<typename BackendT>
class IWidget
{
public:
void doSomething()
{
backend.doSomething();
}
private:
BackendT backend;
};
Qt implementation QtWidget.h:
class QtWidget
{
public:
void doSomething()
{
// qt specifics here
cout << "qt widget" << endl;
}
};
Gtk implementation GtkWidget.h:
class GtkWidget
{
public:
void doSomething()
{
// gtk specifics here
cout << "gtk widget" << endl;
}
};
Qt backend QtBackend.h:
#include "QtWidget.h"
// include all the other gtk classes you implemented...
#include "IWidget.h"
typedef IWidget<QtWidget> Widget;
// map all the other classes...
Gtk backend GtkBackend.h:
#include "GtkWidget.h"
// include all the other gtk classes you implemented...
#include "IWidget.h"
typedef IWidget<GtkWidget> Widget;
// map all the other classes...
Application:
// Choose the backend here:
#include "QtBackend.h"
int main()
{
Widget* w = new Widget();
w->doSomething();
return 0;
}

C++ Using interfaces or not? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm programming a library and I'm defining an interface for each class by making it's functions and destructor pure virtual. Now, over the time, I've experienced many disadvantages of this design (- just to name some of them: no static methods possible, a lot of virtual inheritence, and, of course, virtual functions are extremly slow.)
The only advantage I see in interfaces is to provide the user with a simple interface and hide the complex details behind them.
But considering all the disadvantages, I don't see why even big, known libraries are using interfaces. (f.e. Ogre 3D, Irrlicht and many other 3D libraries, where performance is the most important thing.)
My question is:
Is there a really convincing point which I'm missing why to use interfaces? Why do others do that? What is more common - using interfaces or
not using them?
Also, when using interfaces - is it valid to make some sort of "hybrid" design? Where classes relying on performance are implemented directly on the interface layer to avoid virtual function calls, and all other classes are implemented as usual? Or is this a bad design?
Your questions
Why use interfaces?
"Interfaces" isn't a well defined term in C++: some people consider any base class with virtual methods to be an interface, while others expect there to be no data members, or no public data members, or no private data members; a few people might say all members must be virtual, and others that they must be pure virtual.
There are pros and cons to each design decision:
base classes with virtual functions are C++'s mechanism for runtime polymorphism, which is a great reason to use them
keeping public data out of the base class preserves freedom to calculate the data on the fly
keeping private data out of the base class avoids having to change it therein when only the implementation changes; such changes force a client recompilation rather than a re-link (being able to just relink is especially useful when the implementation's in a shared object / library that's dynamically linked, as only an updated library need be distributed)
virtual dispatch makes it easy to implement state machines (changing the implementatino at run-time), as well as switching in mock implementations for testing
What is more common - using interfaces or not using them?
That's hugely dependent on the type of application, whether the data inputs or state naturally benefit from runtime polymorphism, and the design decisions made by the programmers' involved. C++ is used for such wildly divergent purposes that no general statement's meaningful.
Also, when using interfaces - is it valid to make some sort of "hybrid" design?
Yes - some "hybrid" approaches are listed under "mitigation" below.
Discussion of your remarks
"virtual functions are extremly slow"
Actual virtual dispatch is necessarily out-of-line, so can be about an order of magnitude worse than an inline call if doing something very simple (e.g. getter/setter for int member), but see mitigation below. (Often the optimiser can avoid virtual dispatch if the dynamic type of the variable involved is known at compile time).
"no static methods possible"
Each class can have static methods - there's just no way to invoke them polymorphically, but what would it even mean to do so? You must have some way to know the dynamic/runtime type as that's the basis for selecting which function to call....
Mitigation
There are a LOT of options for tuning performance - what you should often becomes obvious when you very carefully consider your actual performance problem. The following's a random smattering to give a taste of what's possible and occasionally useful....
Mitigation - granularity of work performed by virtual functions
Try to do as much work as possible per virtual function call. For example, a set_pixel function taking a single pixel would normally be bad interface design. A set_pixels function that can take an arbitrarily long list would be much better, but there're many other alternatives such as providing some kind of virtual drawing surface that the client code can work on without runtime polymorphic dispatch, then pass back the entire surface in one virtual function call.
Mitigation - handover to static-polymorphic code
You can manually orchestrate targeted (per performance profiling results) handover from run-time to compile-time polymorphism (albeit at the cost of manually maintaining a centralised handover routine.
Example
Assume a base class B with virtual void f();, and two derived D1, D2.
First, some polyrmophic algorithmic code that explicitly neuters virtual dispatch:
template <typename T>
struct Algo
{
void operator()(T& t)
{
.. do lots of stuff...
t.T::f(); // each t member access explicitly dispatched statically
...lots more...
}
};
Then, some code to dispatch to a static-type-specific instantiation of a specified algorithm based on dynamic type:
template <template <typename> class F>
void runtime_to_compiletime(B& b) {
if (D1* p = dynamic_cast<D1*>(&b))
F<D1>()(*p);
else if (D2* p = dynamic_cast<D2*>(&b))
F<D2>()(*p);
}
Usage:
D1 d1;
D2 d2;
runtime_to_compiletime<Algo>(d1);
runtime_to_compiletime<Algo>(d2);
Mitigation - orchestrate your own type information
If dynamic_cast is too slow in your implementation, you can get lightning fast switching on dynamic type - at the considerable cost of having to maintain it - as follows:
struct Base
{
Base() : type_(0) { }
int get_type() const { return type_; }
protected:
Base(int type) : type_(type) { }
int type_;
};
struct Derived : Base
{
Derived() : Base(1) { }
};
Then fast switching is trivial:
void f(Base* p)
{
switch (p->get_type())
{
... handle using static type in here ...
}
}
Mitigation - data in "interfaces"
Instead of virtual int f() const; to expose an int data member that only a few derived classes need to calculate on the fly, consider:
class Base
{
public:
Base() : virtual_f_(false) { }
int f() const { return virtual_f_ ? virtual_f() : f_; }
private:
int f_;
bool virtual_f_;
virtual int f() const { }
};
Interfaces are just one of the many mechanisms C++ provides to get reusability and extendibility.
Reuse.
If class A has a pointer to concrete class B, you cannot resuse class A withouth B.
Solution: you introduce an interface I implemented by B, and A has a pointer to I. In this way, you can reuse class A in your software (or in other applications) withouth B (please note that you bring I together with A so you need to implement it someway)
Extendibility.
If a class A has a pointer to concrete class B, class A is bounded to use the "algorithms" provided by B. In future, if you need to use different "algorithms", you are forced to modify A source code.
Solution: if A has a pointer to an interface I, you are free to change I implementation (eg. you can substitute B with C, both implementing I) withouth modifying A source code.
(By the way: mock implementations for testing are included in the extendibility case).
Let's recap:
you don't need to define an interface for each class of your software: you only need to put an interface when you need a hot spot for extendibility or reusability (yes: sadly this require you to think about your design instead of adopt blindly a rule...).
C++ offers many techniques to get the same results: instead of interfaces you can use templates or delegates (see std::function, boost::signal and so on).
the advantage you see in interfaces ("to provide the user with a simple interface and hide the complex details behind them") is best obtained by means of encapsulation. You don't need interface classes to get information hiding. It's enough that your classes don't export details in the public section.
I think you can use next approach: when you have multiply implementations of same interface and implementation selection should be performed at runtime (maybe those interface and implementation wrap some kind of "strategy" etc.) then you should use "interface-implementation" approach (with factory creation, etc.), when it's some kind of utility functionality - than you should avoid "interface-implementation" approach. You also should not forget about correct objects creation/destruction calls between libraries and main code. Hope this helps.
Using non intrusive polymorphism http://isocpp.org/blog/2012/12/value-semantics-and-concepts-based-polymorphism-sean-parent can help with problems of multiple inheritance and virtual inheritance by truly separating interface from implementation. This should eliminate the need for virtual inheritance. In my personal opinion virtual inheritance is a sign of bad/old design.
Also if you are using polymorphism in order to achieve the open closed principal then static polymorphism via CRTP can be much faster.
class Base {
virtual void foo(){
//default foo which the suer can override
}
void bar(){
foo();
}
}
class UserObject : public Base{
void foo() override{
//I needed to change default foo,
//this probably cannot be inlined unless the compiler is really
//good at devirtialization
}
}
becomes
template<typename T_Derived>
class Base {
virtual void foo(){
//default foo which the suer can override
}
void bar(){
static_cast<T_Derived*>(this)->foo();
}
}
class UserObject : public Base<UserObject>{
void foo() {
//I needed to change default foo, ths can be inlined no problem
}
}
One advantage with interfaces is that enables you to write unit tests. When writing a component that uses an interface, you can implement a simple fake version of the interface. The fake version can be given to the component to use during unit tests. This means unit tests will be fast as they don't really execute the library operation. Your fake implementation of the interface can be coded to return values and data to your component to cause it to execute certain code paths and the fake implementation can check that the component made expected calls to the interface.
This convinces me! Obviously, not all libraries are the same. Writing a fake version of a 3D graphics library might not always be useful as you really need to use your own eyes to see the image is correct as a unit test might be tricky to code to check the output is correct here. But, for many other applications unit tests are worth the extra work because they give you confidence to make changes to the code base and be sure it still works as behaves, and help ensure quality.

Static CRTP class without knowing derived type?

Given the following, working code.
#include <iostream>
template<class Detail>
class AbstractLogger
{
public:
static void log(const char* str) {
Detail::log_detailled(str);
}
};
class Logger : public AbstractLogger<Logger>
{
public:
static void log_detailled(const char* str) {
std::cerr << str << std::endl;
}
};
int main(void)
{
AbstractLogger<Logger>::log("main function running!");
return 0;
}
Now, I want to put AbstractLogger into a library, and let the library user define his own logger, like the Logger class here. This has one drawback: AbstractLogger<Logger> can not be used inside the library, since the library can not know Logger.
Notes:
Please no virtual functions or questions why not. Also, I am aware of the similar problem that "static virtual" members are invalid. Maybe, there is a workaround in CRTP :)
C++11 will be interesting, however, I need "usual" C++.
If what you mean is that you want to have a library that uses this as a logging mechanism without knowing the exact instantiating type, I would advice against it.
The only way of doing it while meeting your other requirements (i.e. no virtual functions) is that all your functions/types in the library that need to log are converted into templates that take the Logger type. The net result is that most of your interface becomes a template (although you can probably move a good amount of the implementation to non-templated code, it will make your life much harder than needed, and it will still generate a much larger binary).
If your concern with virtual functions is performance, then you should reconsider your approach and the problems it brings. In particular, logging is expensive. Most logging libraries tackle it by optimizing the non-logging case (by means of macros that avoid calling the logger if the log level/group/... are not enabled), but still leave dynamic dispatch for the actual writting. The cost of the dynamic dispatch is negligible compared with the cost of writing to the console, or a file, or even with the cost of generating the message that will be logged (I am assuming that you not only log literal strings)
The usual approach is to code against a concept, while providing helpers so that users may easily produce types that satisfy one or more of those concepts. As an example, something like boost::iterator_facade is a CRTP helper that makes it easier for a user to write an iterator. Then, that iterator can be used anywhere an iterator is accepted -- for instance in the range constructor of std::vector. Notice how that particular constructor has no foreknowledge of the user-defined type.
In your case, AbstractLogger would be the CRTP helper. The missing piece would be to define e.g. a logger concept. As a result, notice that everything that needs a logger either needs to be implemented as a template or you need a type-erasing container to hold arbitrary loggers.
Concept checks (like those provided by Boost) are convenient for this kind of programming, since they allow to represent a concept with actual code.
Template classes can't be 'put in a library' since they are instantiated by the compiler as specializations of their template parameters.
You may put parameter independent stuff used in the template implementation into a library though.

Template or abstract base class?

If I want to make a class adaptable, and make it possible to select different algorithms from the outside -- what is the best implementation in C++?
I see mainly two possibilities:
Use an abstract base class and pass concrete object in
Use a template
Here is a little example, implemented in the various versions:
Version 1: Abstract base class
class Brake {
public: virtual void stopCar() = 0;
};
class BrakeWithABS : public Brake {
public: void stopCar() { ... }
};
class Car {
Brake* _brake;
public:
Car(Brake* brake) : _brake(brake) { brake->stopCar(); }
};
Version 2a: Template
template<class Brake>
class Car {
Brake brake;
public:
Car(){ brake.stopCar(); }
};
Version 2b: Template and private inheritance
template<class Brake>
class Car : private Brake {
using Brake::stopCar;
public:
Car(){ stopCar(); }
};
Coming from Java, I am naturally inclined to always use version 1, but the templates versions seem to be preferred often, e.g. in STL code? If that's true, is it just because of memory efficiency etc (no inheritance, no virtual function calls)?
I realize there is not a big difference between version 2a and 2b, see C++ FAQ.
Can you comment on these possibilities?
This depends on your goals. You can use version 1 if you
Intend to replace brakes of a car (at runtime)
Intend to pass Car around to non-template functions
I would generally prefer version 1 using the runtime polymorphism, because it is still flexible and allows you to have the Car still have the same type: Car<Opel> is another type than Car<Nissan>. If your goals are great performance while using the brakes frequently, i recommend you to use the templated approach. By the way, this is called policy based design. You provide a brake policy. Example because you said you programmed in Java, possibly you are not yet too experienced with C++. One way of doing it:
template<typename Accelerator, typename Brakes>
class Car {
Accelerator accelerator;
Brakes brakes;
public:
void brake() {
brakes.brake();
}
}
If you have lots of policies you can group them together into their own struct, and pass that one, for example as a SpeedConfiguration collecting Accelerator, Brakes and some more. In my projects i try to keep a good deal of code template-free, allowing them to be compiled once into their own object files, without needing their code in headers, but still allowing polymorphism (via virtual functions). For example, you might want to keep common data and functions that non-template code will probably call on many occasions in a base-class:
class VehicleBase {
protected:
std::string model;
std::string manufacturer;
// ...
public:
~VehicleBase() { }
virtual bool checkHealth() = 0;
};
template<typename Accelerator, typename Breaks>
class Car : public VehicleBase {
Accelerator accelerator;
Breaks breaks;
// ...
virtual bool checkHealth() { ... }
};
Incidentally, that is also the approach that C++ streams use: std::ios_base contains flags and stuff that do not depend on the char type or traits like openmode, format flags and stuff, while std::basic_ios then is a class template that inherits it. This also reduces code bloat by sharing the code that is common to all instantiations of a class template.
Private Inheritance?
Private inheritance should be avoided in general. It is only very rarely useful and containment is a better idea in most cases. Common case where the opposite is true when size is really crucial (policy based string class, for example): Empty Base Class Optimization can apply when deriving from an empty policy class (just containing functions).
Read Uses and abuses of Inheritance by Herb Sutter.
The rule of thumb is:
1) If the choice of the concrete type is made at compile time, prefer a template. It will be safer (compile time errors vs run time errors) and probably better optimized.
2) If the choice is made at run-time (i.e. as a result of a user's action) there is really no choice - use inheritance and virtual functions.
Other options:
Use the Visitor Pattern (let external code work on your class).
Externalize some part of your class, for example via iterators, that generic iterator-based code can work on them. This works best if your object is a container of other objects.
See also the Strategy Pattern (there are c++ examples inside)
Templates are a way to let a class use a variable of which you don't really care about the type. Inheritance is a way to define what a class is based on its attributes. Its the "is-a" versus "has-a" question.
Most of your question has already been answered, but I wanted to elaborate on this bit:
Coming from Java, I am naturally
inclined to always use version 1, but
the templates versions seem to be
preferred often, e.g. in STL code? If
that's true, is it just because of
memory efficiency etc (no inheritance,
no virtual function calls)?
That's part of it. But another factor is the added type safety. When you treat a BrakeWithABS as a Brake, you lose type information. You no longer know that the object is actually a BrakeWithABS. If it is a template parameter, you have the exact type available, which in some cases may enable the compiler to perform better typechecking. Or it may be useful in ensuring that the correct overload of a function gets called. (if stopCar() passes the Brake object to a second function, which may have a separate overload for BrakeWithABS, that won't be called if you'd used inheritance, and your BrakeWithABS had been cast to a Brake.
Another factor is that it allows more flexibility. Why do all Brake implementations have to inherit from the same base class? Does the base class actually have anything to bring to the table? If I write a class which exposes the expected member functions, isn't that good enough to act as a brake? Often, explicitly using interfaces or abstract base classes constrain your code more than necessary.
(Note, I'm not saying templates should always be the preferred solution. There are other concerns that might affect this, ranging from compilation speed to "what programmers on my team are familiar with" or just "what I prefer". And sometimes, you need runtime polymorphism, in which case the template solution simply isn't possible)
this answer is more or less correct. When you want something parametrized at compile time - you should prefer templates. When you want something parametrized at runtime, you should prefer virtual functions being overridden.
However, using templates does not preclude you from doing both (making the template version more flexible):
struct Brake {
virtual void stopCar() = 0;
};
struct BrakeChooser {
BrakeChooser(Brake *brake) : brake(brake) {}
void stopCar() { brake->stopCar(); }
Brake *brake;
};
template<class Brake>
struct Car
{
Car(Brake brake = Brake()) : brake(brake) {}
void slamTheBrakePedal() { brake.stopCar(); }
Brake brake;
};
// instantiation
Car<BrakeChooser> car(BrakeChooser(new AntiLockBrakes()));
That being said, I would probably NOT use templates for this... But its really just personal taste.
Abstract base class has on overhead of virtual calls but it has an advantage that all derived classes are really base classes. Not so when you use templates – Car<Brake> and Car<BrakeWithABS> are unrelated to each other and you'll have to either dynamic_cast and check for null or have templates for all the code that deals with Car.
Use interface if you suppose to support different Break classes and its hierarchy at once.
Car( new Brake() )
Car( new BrakeABC() )
Car( new CoolBrake() )
And you don't know this information at compile time.
If you know which Break you are going to use 2b is right choice for you to specify different Car classes. Brake in this case will be your car "Strategy" and you can set default one.
I wouldn't use 2a. Instead you can add static methods to Break and call them without instance.
Personally I would allways prefer to use Interfaces over templates because of several reasons:
Templates Compiling&linking errors are sometimes cryptic
It is hard to debug a code that based on templates (at least in visual studio IDE)
Templates can make your binaries bigger.
Templates require you to put all its code in the header file , that makes the template class a bit harder to understand.
Templates are hard to maintained by novice programmers.
I Only use templates when the virtual tables create some kind of overhead.
Ofcourse , this is only my self opinion.