I want to create a class that can use one of four algorithms (and the algorithm to use is only known at run-time). I was thinking that the Strategy design pattern sounds appropriate, but my problem is that each algorithm requires slightly different parameters. Would it be a bad design to use strategy, but pass in the relevant parameters into the constructor?.
Here is an example (for simplicity, let's say there are only two possible algorithms) ...
class Foo
{
private:
// At run-time the correct algorithm is used, e.g. a = new Algorithm1(1);
AlgorithmInterface* a;
};
class AlgorithmInterface
{
public:
virtual void DoSomething() = 0;
};
class Algorithm1 : public AlgorithmInterface
{
public:
Algorithm1( int i ) : value(i) {}
virtual void DoSomething(){ // Does something with int value };
int value;
};
class Algorithm2 : public AlgorithmInterface
{
public:
Algorithm2( bool b ) : value(b) {}
virtual void DoSomething(){ // Do something with bool value };
bool value;
};
It would be a valid design because the Strategy pattern asks for an interface to be defined and any class that implements it is a valid candidate to run the strategy code, regardless how it is constructed.
I think it's correct, if you have all the parameters you need when you create the new strategy and what you do is clear for everyone reading the code.
You are right on with this approach. Yes this is the essence of the strategy pattern..."Vary the algorithm independent of the implementation." You can just give yourself a generic constructor to pass in the parameters you need to initialize your class, such as an object array.
Enjoy!
Strategy pattern are useful when you want to decide on runtime which algorithm to be used.
You could also pass parameters in using a single interface of a memory block containing key-value pairs. That way the interface is common between any present and future algorithms. Each algorithm implementation would know how to decode the key-value pairs into its parameters.
IMHO, you are facing the challenge as you are confusing between the creational aspect of the concrete algorithm and the actual running of the algorithm. As long as the 'DoSomething' interface remains the same, Strategy Pattern can be used. It is only the creation of the different concrete algorithm that varies in your case, which can be handled through a Factory Method design pattern.
Related
I have a class that will serve as the base class for (many) other classes. The derived classes each have a slight variation in their logic around a single function, which itself will be one of a set group of external functions. I aim to have something which is efficient, clear and will result in the minimal amount of additional code per new deriving class:
Here is what I have come up with:
// ctor omitted for brevity
class Base
{
public:
void process(batch_t &batch)
{
if (previous) previous->process(batch);
pre_process(batch);
proc.process(batch);
post_process(batch);
}
protected:
// no op unless overridden
virtual void pre_process(batch_t &batch) {}
virtual void post_process(batch_t &batch) {}
Processor proc;
Base* previous;
}
Expose the 'process' function which follows a set pattern
The core logic of the function is defined by a drop in class 'Processor'
Allow modification of this pattern via two virtual functions, which define additional work done before/after the call to Processor::proc
Sometimes, this object has a handle to another which must do something else before it, for this I have a pointer 'previous'
Does this design seem good or are there some glaring holes I haven't accounted for? Or are there other common patterns used in situations like this?
Does this design seem good or are there some glaring holes I haven't accounted for? Or are there other common patterns used in situations like this?
Without knowing more about your goals, all I can say is that it seems quite sensible. It's so sensible, in fact, there's a common name for this idiom: A "Non-virtual Interface". Also described as a "Template Method Design Pattern" by the gang of four, if you are in Java-sphere.
You are currently using the so called "Template Method" pattern (see, for instance, here). You have to note that it uses inheritance to essentially modify the behaviour of the process(batch) function by overriding the pre_process and post_process methods. This creates strong coupling. For instance, if you subclass your base class to use a particular pre_process implementation, then you can't use this implementation in any other subclass without duplicating code.
I personally would go with the "Strategy" pattern (see, for instance, here) which is more flexible and allows code re-use more easily, as follows:
struct PreProcessor {
virtual void process(batch&) = 0;
};
struct PostProcessor {
virtual void process(batch&) = 0;
};
class Base {
public:
//ctor taking pointers to subclasses of PreProcessor and PostProcessor
void process(batch_t &batch)
{
if (previous) previous->process(batch);
pre_proc->process(batch);
proc.process(batch);
post_proc->process(batch);
}
private:
PreProcessor* pre_proc;
Processor proc;
PostProcessor* post_proc;
Base* previous;
}
Now, you can create subclasses of PreProcessor and PostProcessor which you can mix and match and then pass to your Base class. You can of course apply the same approach for your Processor class.
Given your information, I don't see any benefit of using Inheritance (one Base and many Derived classes) here. Writing a new (whole) class just because you have a new couple of pre/post process logic is not a good idea. Not to mention, this will make difficult to reuse these logic.
I recommend a more composable design:
typedef void (*Handle)(batch_t&);
class Foo
{
public:
Foo(Handle pre, Handle post, Foo* previous) :
m_pre(pre),
m_post(post),
m_previous(previous) {}
void process(batch_t& batch)
{
if (m_previous) m_previous->process(batch);
(*m_pre)(batch);
m_proc.process(batch);
(*m_post)(batch);
}
private:
Processor m_proc;
Handle m_pre;
Handle m_post;
Foo* m_previous;
}
This way, you can create any customized Foo object with any logic of pre/post process you want. If the creation is repetitive, you can always extract it into a createXXX method of a FooFactory class.
P/S: if you don't like function pointers, you can use whatever representing a function, such as interface with one method, or lambda expression ...
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Ok so I have tried implementing simple mono alphabetic substitution ciphers like Caesars , digraph like playfair , polyalphabetic ones like autokey, vigenre and a few others in c++ {without using classes}. Now i would like to bring together all these ciphers and a few others and package it into a single project.I have started coding a few lines, but i'm not sure how i must design it. Here's how my classes look.
my front end
//main.cpp contains few switch cases to chose the right cipher for encryption.
//cipher.cpp implements class cipher.In a crude format the class looks like
class cipher
{
protected:
string plaintxt,ciphertxt;
public:
virtual bool encrypt()=0;
virtual bool decrypt()=0;
virtual bool tabulate()=0;
}
this class is interfaced by cipher.h
//mono_alphabetic.cpp implemants the class mono_alpha
class mono_alpha : public cipher
{
protected:
map<string,string> Etable,Dtable;
public:
bool Encrypt();
bool Decrypt();
}
Now i'm using a simple example of atbash cipher here.For those of you who don't know what an atbash cipher is, it is a mode of encryption in which each character in a given string is encrypted with its equivalent character as per position in the reverse alphabetic order. For eg. A ->Z Z->A B->Y M->N so on.
class atbash : public mono_alpha
{
public:
bool tabulate(); // makes a hash map were A is mapped to Z M to N e.t.c
atbash(string&); // accepts a string and copies it to string plaintxt.
}
This is a very crude example. Only the class design is presented here.Here are a few doubts of mine.
implemantation : I would accepts a string from the user and then pass it to the constructor of class atbash, where it is copied to the string data member plaintxt inherited from the base class cipher. Then i would invoke the function tabulate from the constructor.Now i have two choices either tabulate() generates a hash map of encryption table and store it in Etable, or it could also generate the decryption table.In the case of an atbash cipher these are one but the same. But what about the case of a general mono alphabetic substitution cipher ? how would i force the tabulate functio to create either one.
my idea was to pass a character argument to the constructor to the constructor which describes if the given string is to be encrypted or decrypted and accordingly saves it in either one among plaintxt or ciphertxt.Further the constructor passes this character argument to tabulate function which tabulates the encryption or decryption table accordingly.Is this good ?
any suggestion on how to improve this ?
interface : my way of implementing an interface to all these ciphers from main.cpp was to use swith case like.
switch(chosen_value)
{
case 1: cout<<"atbash encryption";
cipher*ptr = new atbash ("a string");
// ptr->tabulate(); if it isn't being called directly from the constructor.(here it is)
case 2:
cout<< "caeser's cipher";
.....................
.
.....
}
Are there any better ways to implement this without using switch case.
also as you can see i have used a base class pointer to an object of the derived class for doing this.I know it isn't necessary here and the I can simply proceed by declaring an object. Is there any real importance to referencing objects through a base class pointer ?
I have heard that these base class pointers can be a real life savior sometimes ! If so please direct me on scenarios where this simplifies coding . Is declaring pure virtual functions in the base class not of any use in this particular case.Is it just bloating the code here ?
should i go on with separating the class implementations into separate files like i have done here or should i just cramp up all these code in a single main.cpp which would make inheritance a lot easier as you don't have to use header files.
Please guide me on this.I have zero professional experience in coding and would love to here your opinions.
Some ideas, in no particular order
Have different classes for encryption and for decryption. That will solve your doubt on what to use. So the cipher base class becomes a base class for a transformation of a string into other. (not an expert on patterns, but I believe this is the Command Pattern)
The nice thing about having an object to represent the algorithm is that it can have state. You might want to add a reset() method to be able to reuse the object on a new execution if the creation of the object is expensive.
You can make the base class a function object with an abstract operator(). This operator() gets implemented in each specific encryption and descryption classes. Using this allows you to handle this classes as functions (the downside is that it is perhaps less clear what you're doing).
It is correct to handle everything through pointers to the base class (or references or smart pointers)
In order to create the right type of operation, have a Factory class (this is again a pattern). This can be a class with a creator method where you indicate the algorithm and the encryption/decryption direction. The Factory returns a pointer to the base class, pointing the appropriate implementation.
The implementation can be a vector or a map or an array of some specific factory objects (whose job is to instantiate an algorithm object of the different types)... Alternative you can have a static method on each derived class and store a pointer to method in the structure.
The structure (vector/map/array/whatever) is used for fast selection of the right algorithm. If the number of algorighms is small, the use of a switch statement is probably fine. The structure is contained in the Factory class and initialize on its constructor.
You must mind the lifecycle of the objects created. Objects are created by the Factory, but who should destroy them?
Consider what you're going to use to represent the encrypted/decrypted messages and wether they become non-printable or they can become too large.
There are many design decisions here, many trade offs that depends on different things.
Hope the above lines give you some ideas to start.
Edit: adding a more concrete example
We will start with an Operation class. This assumes that we can have both encrypters and decrypters can be called with the same API
class Operation {
public:
virtual ~Operation() { }
virtual std::string operator()(const std::string &input)=0;
virtual void reset() { }
};
Notes on this:
Assumes that the API is string input gives a string output. This is the operator() pure virtual method.
Added a virtual destructor. We're going to be dealing mostly with references to Operation. However implementations of the algorithm my need to destroy their own things, so the destructor must be virtual so that when deleting an Operation pointer it will also invoke the destructor of the derived class.
Added a reset() method. This has a default implementation that does nothing. Potentially derived classes might store state, this method is intended to return the operation to its initial step so that you don't have to scrap it and create another.
Now some of the derived classes:
class MyEncoder: public Operation {
public:
static Operation *create() {
return new MyEncoder();
}
std::string operator()(const std::string &input) {
// Do things.
return std::string();
}
};
class MyDecoder: public Operation { ... };
class OtherEncoder: public Operation { ... };
class OtherDecoder: public Operation { ... };
I'm only showing in full MyEncoder We see a static method create that we will talk about later.
The implementation of the algorithm happens on the implementation of the operator()
You could:
Keep state in attributes of MyEncoder
Initialize stuff on constructor
... and perhaps destroy things in a destructor.
Potentially include an implementation of the reset() method to reuse the object in another invocation.
Now for the Factory:
class OperationFactory {
public:
enum OperationDirection {
OD_DECODER=0,
OD_ENCODER
};
enum OperationType {
OT_MY=0,
OT_OTHER
};
....
};
Just declared the class and a couple of enumerations to help us distinguish between encoders and decoders and the two algorithm I'm going to use.
We need some place to store things, so the Factory class ends with:
class OperationFactory {
public:
...
private:
typedef Operation *(*Creator)();
typedef std::map<OperationType,Creator> OperationMap;
OperationMap mEncoders;
OperationMap mDecoders;
};
Here:
The first typedef gives a name to a function pointer. This is a function that takes no arguments and returns a pointer to an Operation. A static method is the same as a function (at least regarding function pointers)... so this typedef allows us to give a name to the mysterious create() static method we had above.
The second typedef is just shortcut for the lengthy std::map definition. This is a map from OperatonType to Creator function.
We define two of those maps, one for Encoder, one for Decoders. You could devise a different way.
With that we can provide some methods for the user to obtain what it wants:
class OperationFactory {
public:
...
Operation *getOperation(OperationDirection _direction,OperationType _type) const {
switch(_direction) {
case OD_DECODER:
return getDecoder(_type);
case OD_ENCODER:
return getEncoder(_type);
default:
// Or perhaps throw an exception
return 0;
}
}
Operation *getEncoder(OperationType _type) const {
OperationMap::const_iterator it=mEncoders.find(_type);
if(it!=mEncoders.end()) {
Creator creator=it->second;
return (*creator)();
} else {
// Or perhaps throw an exception
return 0;
}
}
Operation *getDecoder(OperationType _type) const {
.... // similar but over the mDecoders
}
....
};
So, we look up the OperationType in the map and get a pointer to a function (Creator) type, we can call this function (*creator)() to obtain the instance of the Operation that we requested.
Some words on (*creator)():
creator is of type Creator... so it is a pointer to a function.
(*creator) is the function (the same as if p is an int *, *p is of type int)...
(*creator)() is the invocation of a function.
To complete this we need to really have something in the map... so we add that on the constructor:
class OperationFactory {
public:
....
OperationFactory() {
mEncoders[OT_MY]=&MyEncoder::create;
mEncoders[OT_MY]=&MyDecoder::create;
mEncoders[OT_OTHER]=&OtherEncoder::create;
mEncoders[OT_OTHER]=&OtherDecoder::create;
}
....
};
We insert for each algorithm the pointer to their create static methods.
Finally how do we use it?
int main(int argc,char **argv) {
OperationFactory f;
Operation *o=f.getOperation(OperationFactory::OD_DECODER,OperationFactory::OT_MY);
std::string toTransform="Hello world";
std::string transformed=(*o)(toTransform);
delete o; // don't forget to delete it.
}
Here we have an instance of the OperationFactory f from where we can request the creation of our desired operation with the getOperation() methods.
The object that we got can be used to execute the algorithm. Note that (*o)(toTransform) is formaly similar to our invocation of creator above, but there are differences:
o is a pointer to an object of type Operation (actually is really a pointer MyEncoder)
(*o) is an object of typeOperation(well, really of typeMyEnconder`)
(*o)(toTransform) is the invocation of the operator() method of the MyEncoder type.
We could have used this technique on the Creator: using an object-function instead of a pointer to function... but it would have been more code.
Note that the factory allocates memory... and this memory must be disposed when no longer needed. Ways of not doing this are to use unique_ptr or shared_ptr...
Note that getOperation() could return a null pointer when it cannot find the algorithm requested... so the calling code should check for that possibility.
Alternatively the implementation of getOperation() could have chosen to throw an exception when the algorithm is not found... again the calling code should then have had a try/catch.
Now, how to add a new algorithm:
Derive and implement your encoder and decoder classes from Operation
Expand the enum OperationType
register the creators in the OperationFactory constructor.
... use it.
I fear something like this is answered somewhere on this site, but I can't find it because I don't even know how to formulate the question. So here's the problem:
I have a voxel drowing function. First I calculate offsets, angles and stuff and after I do drowing. But I make few versions of every function because sometimes I want to copy pixel, sometimes blit, sometimes blit 3*3 square for every pixel for smoothing effect, sometimes just copy pixel to n*n pixels on the screen if object is resized. And there's tons of versions for that small part in the center of a function.
What can I do instead of writing 10 of same functions which differ only by central part of code? For performance reasons, passing a function pointer as an argument is not an option. I'm not sure making them inline will do the trick, because arguments I send differ: sometimes I calculate volume(Z value), sometimes I know pixels are drawn from bottom to top.
I assume there's some way of doing this stuff in C++ everybody knows about.
Please tell me what I need to learn to do this. Thanks.
The traditional OO approaches to this are the template method pattern and the strategy pattern.
Template Method
The first is an extension of the technique described in Vincenzo's answer: instead of writing a simple non-virtual wrapper, you write a non-virtual function containing the whole algorithm. Those parts that might vary, are virtual function calls.
The specific arguments needed for a given implementation, are stored in the derived class object that provides that implementation.
eg.
class VoxelDrawer {
protected:
virtual void copy(Coord from, Coord to) = 0;
// any other functions you might want to change
public:
virtual ~VoxelDrawer() {}
void draw(arg) {
for (;;) {
// implement full algorithm
copy(a,b);
}
}
};
class SmoothedVoxelDrawer: public VoxelDrawer {
int radius; // algorithm-specific argument
void copy(Coord from, Coord to) {
blit(from.dx(-radius).dy(-radius),
to.dx(-radius).dy(-radius),
2*radius, 2*radius);
}
public:
SmoothedVoxelDrawer(int r) : radius(r) {}
};
Strategy
This is similar but instead of using inheritance, you pass a polymorphic Copier object as an argument to your function. Its more flexible in that it decouples your various copying strategies from the specific function, and you can re-use your copying strategies in other functions.
struct VoxelCopier {
virtual void operator()(Coord from, Coord to) = 0;
};
struct SmoothedVoxelCopier: public VoxelCopier {
// etc. as for SmoothedVoxelDrawer
};
void draw_voxels(arguments, VoxelCopier ©) {
for (;;) {
// implement full algorithm
copy(a,b);
}
}
Although tidier than passing in a function pointer, neither the template method nor the strategy are likely to have better performance than just passing a function pointer: runtime polymorphism is still an indirect function call.
Policy
The modern C++ equivalent of the strategy pattern is the policy pattern. This simply replaces run-time polymorphism with compile-time polymorphism to avoid the indirect function call and enable inlining
// you don't need a common base class for policies,
// since templates use duck typing
struct SmoothedVoxelCopier {
int radius;
void copy(Coord from, Coord to) { ... }
};
template <typename CopyPolicy>
void draw_voxels(arguments, CopyPolicy cp) {
for (;;) {
// implement full algorithm
cp.copy(a,b);
}
}
Because of type deduction, you can simply call
draw_voxels(arguments, SmoothedVoxelCopier(radius));
draw_voxels(arguments, OtherVoxelCopier(whatever));
NB. I've been slightly inconsistent here: I used operator() to make my strategy call look like a regular function, but a normal method for my policy. So long as you choose one and stick with it, this is just a matter of taste.
CRTP Template Method
There's one final mechanism, which is the compile-time polymorphism version of the template method, and uses the Curiously Recurring Template Pattern.
template <typename Impl>
class VoxelDrawerBase {
protected:
Impl& impl() { return *static_cast<Impl*>(this); }
void copy(Coord from, Coord to) {...}
// *optional* default implementation, is *not* virtual
public:
void draw(arg) {
for (;;) {
// implement full algorithm
impl().copy(a,b);
}
}
};
class SmoothedVoxelDrawer: public VoxelDrawerBase<SmoothedVoxelDrawer> {
int radius; // algorithm-specific argument
void copy(Coord from, Coord to) {
blit(from.dx(-radius).dy(-radius),
to.dx(-radius).dy(-radius),
2*radius, 2*radius);
}
public:
SmoothedVoxelDrawer(int r) : radius(r) {}
};
Summary
In general I'd prefer the strategy/policy patterns for their lower coupling and better reuse, and choose the template method pattern only where the top-level algorithm you're parameterizing is genuinely set in stone (ie, when you're either refactoring existing code or are really sure of your analysis of the points of variation) and reuse is genuinely not an issue.
It's also really painful to use the template method if there is more than one axis of variation (that is, you have multiple methods like copy, and want to vary their implementations independently). You either end up with code duplication or mixin inheritance.
I suggest using the NVI idiom.
You have your public method which calls a private function that implements the logic that must differ from case to case.
Derived classes will have to provide an implementation of that private function that specializes them for their particular task.
Example:
class A {
public:
void do_base() {
// [pre]
specialized_do();
// [post]
}
private:
virtual void specialized_do() = 0;
};
class B : public A {
private:
void specialized_do() {
// [implementation]
}
};
The advantage is that you can keep a common implementation in the base class and detail it as required for any subclass (which just need to reimplement the specialized_do method).
The disadvantage is that you need a different type for each implementation, but if your use case is drawing different UI elements, this is the way to go.
You could simply use the strategy pattern
So, instead of something like
void do_something_one_way(...)
{
//blah
//blah
//blah
one_way();
//blah
//blah
}
void do_something_another_way(...)
{
//blah
//blah
//blah
another_way();
//blah
//blah
}
You will have
void do_something(...)
{
//blah
//blah
//blah
any_which_way();
//blah
//blah
}
any_which_way could be a lambda, a functor, a virtual member function of a strategy class passed in. There are many options.
Are you sure that
"passing a function pointer as an argument is not an option"
Does it really slow it down?
You could use higher order functions, if your 'central part' can be parameterized nicely.
Here is a simple example of a function that returns a function which adds n to its argument:
#include <iostream>
#include<functional>
std::function<int(int)> n_adder(int n)
{
return [=](int x){return x+n;};
}
int main()
{
auto add_one = n_adder(1);
std::cout<<add_one(5);
}
You can use either Template Method pattern or Strategy pattern.
Usually Template method pattern is used in white-box frameworks, when you need to know about the internal structure of a framework to correctly subclass a class.
Strategy pattern is usually used in black-box frameworks, when you should not know about the implementation of the framework, since you only need to understand the contract of the methods you should implement.
For performance reasons, passing a function pointer as an argument is not an option.
Are you sure that passing one additional parameter and will cause performance problems? In this case you may have similar performance penalties if you use OOP techniques, like Template method or Strategy. But it is usually necessary to use profilier to determine what is the source of the performance degradation. Virtual calls, passing additional parameters, calling function through a pointer are usually very cheap, comparing to complex algorithms. You may find that these techniques consumes insignificant percent of CPU resources comparing to other code.
I'm not sure making them inline will do the trick, because arguments I send differ: sometimes I calculate volume(Z value), sometimes I know pixels are drawn from bottom to top.
You could pass all the parameter required for drawing in all cases. Alternatively if use Tempate method pattern a base class could provide methods that can return the data that could be required for drawing in different cases. In Strategy pattern, you could pass an instance of an object that could provide this kind of data to a Strategy implementation.
I have a reasonably-sized class that implements several logically-related algorithms (from graph theory). About 10-15 parameters are required as input to the algorithm. These are not modified by the algorithm, but are used to guide the operation of it. First, I explain two options for implementing this. My question is what is a common way to do so (whether it is or isn't one of the two options).
I personally don't like to pass these values as parameters to the function when N is large, especially while I'm still developing the algorithm.
void runAlgorithm(int param1, double param2, ..., bool paramN);
Instead I have a class Algorithm that contains the algorithms, and I have a struct AlgorithmGlobals that contains these parameters. I either pass this struct to:
void runAlgorithm(AlgorithmGlobals const & globals);
Or I add a public AlgorithmGlobals instance to the class:
class Algorithm {
public:
AlgorithmGlobals globals;
void runAlgorithm();
}
Then elsewhere I'd use it like this:
int main() {
Algorithm algorithm;
algorithm.globals.param1 = 5;
algorithm.globals.param2 = 7.3;
...
algorithm.globals.paramN = 5;
algorithm.runAlgorithm();
return 0;
}
Note that the constructor of AlgorithmGlobals defines good defaults for each of the parameters so only the parameters with non-default values need to be specified.
AlgorithmGlobals are not made private, because they can be freely modified before the runAlgorithm() function is called. There is no need to "protect" them.
This is called the "Parameter object" pattern, and it's generally a good thing. I don't like the member version, especially calling it "XGlobals" and implying that it's shared all over the place. The Parameter Object pattern instead generally involves creating an instance of the Parameter Object and passing it as a parameter to a function call.
Others have mentioned Parameter Object, but there is also another possibility: using a Builder.
Builder allows you to omit the parameters whose default values are suitable, thus simplifying your code. This is especially handy if you are going to use your algorithm with several different sets of parameters. OTOH it also allows you to reuse similar sets of parameters (although there is a risk of inadvertent reuse). This (together with method chaining) would allow you to write code such as
Algorithm.Builder builder;
Algorithm a1 = builder.withParam1(1).withParam3(18).withParam8(999).build();
...
Algorithm a2 = builder.withParam2(7).withParam5(298).withParam7(6).build();
You have several different ideas that you should be suggesting with your design:
The parameters are purely inputs.
The parameters are specific to your algorithm.
The paramaters have default values that are sane.
class Algorithm {
public:
class Parameters { // Nested class, these are specific to your algorithm.
public:
Parameters() : values(sensible_default) { }
type_t values; // This is all about the data.
};
Algorithm(const Parameters ¶ms) : params_(params) { }
void run();
private:
const Parameters params_; // Paramaeters don't change while algorithm
}; // is running.
This is what I would suggest.
I use this technique that you already mentioned:
void runAlgorithm(AlgorithmGlobals const & globals);
But would call the class AlgorithmParams instead.
The Named Parameter Idiom might be useful here.
a.runAlgorithm() = Parameters().directed(true).weight(17).frequency(123.45);
suggestion Why don't you do this instead:
class Algorithm {
public:
Algorithm::Algorithm(AlgorithmGlobals const & globals) : globals_(globals) {}
void runAlgorithm(); // use globals_ inside this function
private:
const AlgorithmGlobals globals_;
};
Now you can use it as such:
AlgorithmGlobals myglobals;
myglobals.somevar = 12;
Algorithm algo(myglobals);
I have two classes that are almost identical, besides one method. The classes have the same data part and all the member functions but one:
class A {
private:
double data;
public:
double calc(){
return data*data;
}
double especific(){
return 2.0*data;
}
}
and the second class is identical, besides the especific method.
This member function in particular needs all the member data to calculate, so passing by value or reference is not an option. Is there a way to implement this without a lot of code duplication? Either using only one class or using templates, but not inheritance (huge performance impact).
Thanks
EDIT: Thanks for all the responses. The Strategy pattern can help in my case, I will try it and see if it works. I'm avoiding virtual inheritance as the plague based on some tests that I did in a different program. This routine will be called everywhere, and performance is a very important factor.
This sounds like a job for the Strategy pattern. It can be implemented in this case as a template parameter. Often it would be implemented as a constructor parameter or a setter method on the class, but that would require inheritance to work properly.
In this case, something like:
template <class SpecificStrategy>
class A {
private:
double data;
public:
double calc(){
return data*data;
}
double especific() {
return SpecificStrategy::especific(data);
}
};
class DoubleStrategy {
static double especific(double data) {
return 2 * data;
}
};
class TripleStrategy {
static double especific(double data) {
return 3 * data;
}
};
Then you can refer to:
A<DoubleStrategy> x;
A<TripleStrategy> y;
x and y will be of completely unrelated types, but it sounds like that's not what you want in this case.
Now, in my opinion using a virtual function and inheritance is the way to go. As someone else pointed out, the performance penalty isn't that large. However there are circumstances in which I could see that it would be a bad idea.
For example, if this class is intended to represent a vector in a graphics package and you're going to be doing the same transform to millions of them, then I could see how you would not want a virtual function call to be a part of the code that did the transform. In fact, you would want to avoid pointer dereferences of any kind of you could at all help it.
Maybe I'm missing the point but why not have a base class that implements all the common functionality and a pure virtual especific() and then inherit this and have the child classes implement especific() as required. Make the data member protected.
class BaseA
{
protected:
double data;
public:
double calc(){
return data*data;
}
virtual double especific() = 0;
};
class A1 : BaseA
{
double especific()
{
return data * 2;
}
};
WRT to the huge performance impact of inheritance... I think this isn't likely unless the cost of vtable lookups is significant compared with the work being done in the method body and you're doing this in a tight loop what's consuming most of your application processing.
If you don't make any members virtual and define your classes intelligently there should be no performance impact whatsoever from inheritence.
All inheritence is saying is "make this class like that one, but with this extra stuff". It is no different at runtime than if you'd typed the same stuff twice.
I suppose you could make a performance impact by doing a bunch of unnesscary stuff in the constructor for the parent class that the child classes don't need. But you won't be that stupid. I have faith in you.
Why two classes at all? If the classes share the same data, you may just want to implement both functions in one class.
class A {
private:
double data;
public:
double calc(){
return data*data;
}
double especific(){
return 2.0*data;
}
double eMoreSpecific() {
return 23.0*data;
}
have a base class with all the common stuff and derive the two classes from it
As others have pointed out
a) this is exactly what inheritance was designed for
b) there is no perfomance overhead whatsoever
c) there are no nasty gotchas lurking anywhere
Many people will comment on this and say 'ah but what about xxxx'; these will be valid comments for advanced and corner case use; except you are not going to do any of them based on the simplicity of what you asked for.
Check out the Strategy Pattern
You could have your class take a functor which especific then calls. You can supply different functors for different ways of calculating the output. There are several other ways you can implement Strategy as well.
I have a feeling that a Bridge pattern might be a good approach for you as it sounds like you want to have unique implementations for your common abstraction.
There are several ways to do this, many of which you've named:
Inheritance from a common base class (which does most of the work), and virtual especific()
One class, with two slightly differently-named especific() methods (or overloaded methods)
Use template specialisation
Have A and B use some other class C to do the majority of the work.
There may be others.
You'll need to choose one of these based on the semantics of your classes and application, and any other specific constraints or requirements.
check out the "inheritance pattern"