While designing an interface for a class I normally get caught in two minds whether should I provide member functions which can be calculated / derived by using combinations of other member functions. For example:
class DocContainer
{
public:
Doc* getDoc(int index) const;
bool isDocSelected(Doc*) const;
int getDocCount() const;
//Should this method be here???
//This method returns the selected documents in the contrainer (in selectedDocs_out)
void getSelectedDocs(std::vector<Doc*>& selectedDocs_out) const;
};
Should I provide this as a class member function or probably a namespace where I can define this method? Which one is preferred?
In general, you should probably prefer free functions. Think about it from an OOP perspective.
If the function does not need access to any private members, then why should it be given access to them? That's not good for encapsulation. It means more code that may potentially fail when the internals of the class is modified.
It also limits the possible amount of code reuse.
If you wrote the function as something like this:
template <typename T>
bool getSelectedDocs(T& container, std::vector<Doc*>&);
Then the same implementation of getSelectedDocs will work for any class that exposes the required functions, not just your DocContainer.
Of course, if you don't like templates, an interface could be used, and then it'd still work for any class that implemented this interface.
On the other hand, if it is a member function, then it'll only work for this particular class (and possibly derived classes).
The C++ standard library follows the same approach. Consider std::find, for example, which is made a free function for this precise reason. It doesn't need to know the internals of the class it's searching in. It just needs some implementation that fulfills its requirements. Which means that the same find() implementation can work on any container, in the standard library or elsewhere.
Scott Meyers argues for the same thing.
If you don't like it cluttering up your main namespace, you can of course put it into a separate namespace with functionality for this particular class.
I think its fine to have getSelectedDocs as a member function. It's a perfectly reasonable operation for a DocContainer, so makes sense as a member. Member functions should be there to make the class useful. They don't need to satisfy some sort of minimality requirement.
One disadvantage to moving it outside the class is that people will have to look in two places when the try to figure out how to use a DocContainer: they need to look in the class and also in the utility namespace.
The STL has basically aimed for small interfaces, so in your case, if and only if getSelectedDocs can be implemented more efficiently than a combination of isDocSelected and getDoc it would be implemented as a member function.
This technique may not be applicable anywhere but it's a good rule of thumbs to prevent clutter in interfaces.
I agree with the answers from Konrad and jalf. Unless there is a significant benefit from having "getSelectedDocs" then it clutters the interface of DocContainer.
Adding this member triggers my smelly code sensor. DocContainer is obviously a container so why not use iterators to scan over individual documents?
class DocContainer
{
public:
iterator begin ();
iterator end ();
// ...
bool isDocSelected (Doc *) const;
};
Then, use a functor that creates the vector of documents as it needs to:
typedef std::vector <Doc*> DocVector;
class IsDocSelected {
public:
IsDocSelected (DocContainer const & docs, DocVector & results)
: docs (docs)
, results (results)
{}
void operator()(Doc & doc) const
{
if (docs.isDocSelected (&doc))
{
results.push_back (&doc);
}
}
private:
DocContainer const & docs;
DocVector & results;
};
void foo (DocContainer & docs)
{
DocVector results;
std :: for_each (docs.begin ()
, docs.end ()
, IsDocSelected (docs, results));
}
This is a bit more verbose (at least until we have lambdas), but an advantage to this kind of approach is that the specific type of filtering is not coupled with the DocContainer class. In the future, if you need a new list of documents that are "NotSelected" there is no need to change the interface to DocContainer, you just write a new "IsDocNotSelected" class.
The answer is proabably "it depends"...
If the class is part of a public interface to a library that will be used by many different callers then there's a good argument for providing a multitude of functionality to make it easy to use, including some duplication and/or crossover. However, if the class is only being used by a single upstream caller then it probably doesn't make sense to provide multiple ways to achieve the same thing. Remember that all the code in the interface has to be tested and documented, so there is always a cost to adding that one last bit of functionality.
I think this is perfectly valid if the method:
fits in the class responsibilities
is not too specific to a small part of the class clients (like at least 20%)
This is especially true if the method contains complex logic/computation that would be more expensive to maintain in many places than only in the class.
Related
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.
I'm trying to program a genetic algorithm for a project and am having difficulty keeping different functions separate. I've been reading up on policy-based design, and this seems like a solution to the problem, but I don't really understand how to implement it.
I've got an OptimizerHost, which inherits from a SelectionPolicy (to determine what solutions are evaluated) and a FitnessPolicy (to determine the fitness of any given solution). The problem is I can't figure out how the two policies can communicate with one another. The bulk of the algorithm is implemented in the SelectionPolicy, but it still needs to be able to check the fitness of its solutions. The only thing I can think of is to implement the SelectionPolicy algorithm in the OptimizerHost itself, so then it will inherit the things it needs from the FitnessPolicy. But that seems like its missing the point of using policies in the first place. Am I misunderstanding something?
I'm not very familiar with the Policy-Based design principles (sorry) but when I read your problem, I felt like you need something like pure virtual classes (as interfaces) to help you through it.
The thing is, you cannot use something from the other, if it's not previously declared: this is the basic rule. Thus, you need to use and virtual interface to say SelectPolicy that FitnessPolicy has some members to be used. Please follow the example, and change it accordingly to your algortihms-needs.
First: create the interfaces for the SelectionPolicy and the FitnessPolicy
template <class T> class FitnessPolicyBase
{
public:
virtual int Fitness(T fitnessSet); // assuming you have implemented the required classes etc. here - return value can be different of course
...
} // write your other FitnessPolicy stuff here
template <class T> class SelectionPolicyBase
{
public:
virtual T Selector(FitnessPolicyBase<Solution> evaluator, Set<T> selectionSet); // assuming such a set exists here
...
} // write your other selectionpolicy interface here
Now, since we made these classes pure virtual (they have nothing but virtual functions) we cannot use them but only inherit from them. This is precisely what we'll do: The SelectionPolicy class and the FitnessPolicy class will be inheriting from them, respectively:
class SelectionPolicy: public SelectionPolicyBase<Solution> // say, our solutions are of Solution Type...
{
public:
virtual Solution Selector(FitnessPolicyBase<Solution> evaluator, Set<Solution> selectionSet); // return your selected item in this function
...
}
class FitnessPolicy : public FitnessPolicy Base<Solution> // say, our solutions are of SolutionSet Type...
{
public:
virtual int Fitness(Solution set); // return the fitness score here
...
}
Now, our algortihm can run with two types of parameters: SolutionSetBase and FitnessSetBase. Did we really need the xxxBase types at all? Not actually, as long as we have the public interfaces of the SolutionPolicy and FitnessPolicy classes, we could use them; but using this way, we kinda seperated the `logic' from the problem.
Now, our Selection Policy algorithm can take references to the policy classes and then call the required function. Note here that, policy classes can call each others' classes as well. So this is a valid situation now:
virtual Solution SelectionPolicy::Selector(FitnessPolicyBase<Solution> evaluator, Set<T> selectionSet)
{
int score = evaluator.Fitness(selectionSet[0]); //assuming an array type indexing here. Change accordingly to your implementation and comparisons etc.
}
Now, in order for this to work, though, you must have initialized a FitnessPolicy object and pass it to this Selector. Due to upcasting and virtual functions, it will work properly.
Please forgive me if I've been overcomplicating things - I've been kinda afar from C++ lately (working on C# recently) thus might have mistaken the syntax an stuff, but logic should be the same anyway.
I think I understand the difference between interface and abstract. Abstract sets default behavior and in cases of pure abstract, behavior needs to be set by derived class. Interface is a take what you need without the overhead from a base class. So what is the advantage of interface over composition? The only advantage I can think is use of protected fields in the base class. What am I missing?
Your title does not make sense, and your explanations are a bit blurry, so let's define the terms (and introduce the key missing one).
There are two different things going on here:
Abstract Class vs Interface
Inheritance vs Composition
Let us start with Interfaces and Abstract Classes.
An Abstract Class (in C++) is a class which cannot be instantiated because at least one its method is a pure virtual method.
An Interface, in Java-like languages, is a set of methods with no implementation, in C++ it is emulated with Abstract Classes with only pure virtual methods.
So, in the context of C++, there is not much difference between either. Especially because the distinction never took into account free-functions.
For example, consider the following "interface":
class LessThanComparable {
public:
virtual ~LessThanComparable() {}
virtual bool less(LessThanComparable const& other) const = 0;
};
You can trivially augment it, even with free functions:
inline bool operator<(LessThanComparable const& left, LessThanComparable const& right) {
return left.less(right);
}
inline bool operator>(LessThanComparable const& left, LessThanComparable const& right) {
return right.less(left);
}
inline bool operator<=(LessThanComparable const& left, LessThanComparable const& right) {
return not right.less(left);
}
inline bool operator>=(LessThanComparable const& left, LessThanComparable const& right) {
return not left.less(right);
}
In this case, we provide behavior... yet the class itself is still an interface... oh well.
The real debate, therefore, is between Inheritance and Composition.
Inheritance is often misused to inherit behavior. This is bad. Inheritance should be used to model a is-a relationship. Otherwise, you probably want Composition.
Consider the simple use case:
class DieselEngine { public: void start(); };
Now, how do we build a Car with this ?
If you inherit, it will work. However, suddenly you get such code:
void start(DieselEngine& e) { e.start(); }
int main() {
Car car;
start(car);
}
Now, if you decide to replace DieselEngine with WaterEngine, the above function does not work. Compilation fails. And having WaterEngine inherit from DieselEngine certainly feels ikky...
What is the solution then ? Composition.
class Car {
public:
void start() { engine.start(); }
private:
DieselEngine engine;
};
This way, noone can write nonsensical code that assumes that a car is an engine (doh!). And therefore, changing the engine is easy with absolutely no customer impact.
This means that there is less adherence between your implementation and the code that uses it; or as it is usually referred to: less coupling.
The rule of thumb is that in general, inheriting from a class which has data or implement behavior should be frown upon. It can be legitimate, but there are often better ways. Of course, like all rule of thumb, it is to be taken with a grain of salt; be careful of overengineering.
An interface defines how you will be used.
You inherit in order to be reused. This means you want to fit into some framework. If you don't need to fit into a framework, even one of your own making, don't inherit.
Composition is an implementation detail. Don't inherit in order to get the implementation of the base class, compose it. Only inherit if it allows you to fit into a framework.
An interface defines behaviour. An abstract class helps to implement behaviour.
In theory there is not a lot of difference between a pure abstract class with no implementation at all, and an interface. Both define an unimplemented API. However, pure abstract classes are often used in languages that don't support interfaces to provide interface like semantics (eg C++).
When you have the choice, generally an abstract base will provide some level of functionality, even if it's not complete. It helps implementation of common behaviour. The downside being you are forced to derive from it. When you are simply defining usage, use an interface. (There's nothing stopping you creating an abstract base that implements an interface).
Interfaces are thin, in C++ they can be described as classes with only pure virtual functions. Thin is good because
it reduces the learning curve in using or implementing the interface
it reduces the coupling (dependency) between the user and the implementor of the interface. Therefore, the user is really well insulated from changes in the implementation of the interface that they are using.
This, in conjunction with dynamic library linking, helps facilitate plug and play, one of the unsung but great software innovations of recent times. This leads to greater software interoperability, extensibility etc.
Interfaces can be more work to put in place. Justify their adoption when you have an important subsystem that could have more than one possible implementation, some day. The subsystem should in that case be used through an interface.
Reuse by means of inheiritance requires more knowlegde of the behaviour of the implementation you are overriding so there is greater "coupling". That said it is also a valid approach in cases where interfaces are overkill.
If type Y inherits from type X, then code which knows how to deal with objects of type X will, in most cases, automatically be able to deal with objects of type Y. Likewise, if type Z implements interface I, then code which knows how to use objects about which implement I, without having to know anything about them, will automatically be able to use objects of type Z. The primary purpose of inheritance and interfaces is to allow such substitutions.
By contrast, if object of type P contains an object of type Q, code which expects to work with an object of type Q will not be able to work on one of type P (unless P inherits from Q in addition to holding an object of that type). Code that expects to manipulate an object of type Q will be able to operate on the Q instance contained within P, but only if the code for P explicitly either supplies it to that code directly, or makes it available to outside code which does so.
I have three classes which each store their own array of double values. To populate the arrays I use a fairly complex function, lets say foo(), which takes in several parameters and calculates the appropriate values for the array.
Each of my three classes uses the same function with only minor adjustments (i.e. the input parameters vary slightly). Each of the classes is actually quite similar although they each perform separate logic when retrieving the values of the array.
So I am wondering how should I 'share' the function so that all classes can use it, without having to duplicate the code?
I was thinking of creating a base class which contained the function foo() and a virtual get() method. My three classes could then inherit this base class. Alternatively, I was also thinking perhaps a global function was the way to go? maybe putting the function into a namespace?
If the classes have nothing in common besides this foo() function, it is silly to put it in a base class; make it a free function instead. C++ is not Java.
Declaring of a function in base class sounds the most appropriate solution. Not sure if you need virtual "get" though, instead just declare the array in the base class and provide access method(s) for descendants.
More complex part is "the input parameters vary slightly". If parameters differ by type only then you may write a template function. If difference is more significant than the only solution I see is splitting main function into several logic blocks and using these blocks in descendant classes to perform final result.
If your classes are quite similar, you could create a template class with three different implementations that has the function foo<T>()
Implement that function in base class. If these classes are similar as you say, they should be derived from one base class anyway! If there are several functions like foo(), it might be reasonable in some cases to combine them into another class which is utilized by/with your classes.
If the underlying data of the class is the same (Array of doubles), considering using a single class and overloading the constructor, or just use 3 different functions:
void PopulateFromString(const string&)
void PopulateFromXml(...)
void PopulateFromInteger(...)
If the data or the behavior is different in each class type, then your solution of base class is good.
You can also define a function in the same namespace as your classes as utility function, if it has nothing to do with specific class behavior (Polymorphism). Bjarne StroupStroup recommends this method by the way.
For the purpose of this answer, I am assuming the classes you have are not common in any other outwards way; they may load the same data, but they are providing different interfaces.
There are two possible situations here, and you haven't told us which one it is. It could be more like
void foo(double* arr, size_t size) {
// Some specific code (that probably just does some preparation)
// Lots of generic code
// ...
// Some more specific code (cleanup?)
}
or something similar to
void foo(double* arr, size_t size) {
// generic_code();
// ...
// specific_code();
// generic_code();
// ...
}
In the first case, the generic code may very well be easy to put into a separate function, and then making a base class doesn't make much sense: you'll probably be inheriting from it privately, and you should prefer composition over private inheritance unless you have a good reason to. You could put the new function in its own class if it benefits from it, but it's not strictly necessary. Whether you put it in a namespace or not depends on how you're organising your code.
The second case is trickier, and in that case I would advise polymorphism. However, you don't seem to need runtime polymorphism for this, and so you could just as well do it compile-time. Using the fact that this is C++, you can use CRTP:
template<typename IMPL>
class MyBase {
void foo(double* arr, size_t size) {
// generic code
// ...
double importantResult = IMPL::DoALittleWork(/* args */);
// more generic code
// ...
}
};
class Derived : MyBase<Derived> {
static double DoALittleWork(/* params */) {
// My specific stuff
return result;
}
};
This gives you the benefit of code organisation and saves you some virtual functions. On the other hand, it does make it slightly less clear what functions need to be implemented (although the error messages are not that bad).
I would only go with the second route if making a new function (possibly within a new class) would clearly be uglier. If you're parsing different formats as Andrey says, then having a parser object (that would be polymorphic) passed in would be even nicer as it would allow you to mock things with less trouble, but you haven't given enough details to say for sure.
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.