Designing A class with multiple set of method implementation [c++] - c++

I am working on an existing project which has one class for which I need an alternate member function definition. I don't want to modify existing member functions or their signatures, just an alternate definition which has to be selected run time based on some xml file (Compile time flag not preferred).
I am new to C++, so this may be a stupid question.
Please suggest design guidelines such that I don't have to change and test existing code base, and just plug my implementation.
Example
class ABC{
public:
int operate(int, int);
}
//Assume below method to be existing implementation
ABC::operate(int op1, int op2)
{
return op1+ op2; //add
}
//Alternate desired implementation
ABC::operate(int op1, int op2)
{
return op1 * op2; //multiply
}
Ideally I would want above to be run time selection but can fall to compile time if thats the only way.

note this thread Reason for C++ member function hiding regarding name-hiding in inheritence.
When a derived class implements a NON VIRTUAL method with the same name as in the base class, that method in the base becomes hidden, and only the derived method can be used - through objects of static type Derived.
My suggestion for you is to implement something like
class ABC{
public:
int operate(int, int);
};
//Assume below method to be existing implementation
ABC::operate(int op1, int op2)
{
return op1+ op2; //add
}
Now, for your extended functionality, derive from ABC (sidenote: inheritence or composition is another discussion, read about it on google).
class Derived : public ABC{
operate(int op1, int op2){
return op1 * op2; //multiply
}
}
Now, wherever you need your new functionality, change the static type of the calling object to Derived, and the derived operate will be called.
A more logical solution is possible if it is possible to change ABC's operate's signature to virtual int operate(int,int);, then polimorphism could take place, and accessing operate through reference types anywhere would invoke the operate that belongs to the dynamic type of the calling object.
Thus, you would only have to instantiate your object to be of type Derived rather than ABC.
Note that virtual method usage is not possible if operate is static, and it was unclear here if that is the case.

I was preparing an answer but Gulzar answered meanwhile ( end of his answer )
What you need is a base notion/mechanism in C++ called dynamic binding ( maybe you learned it also meanwhile as your post is 1 month old )
#include <iostream>
#include <cstddef>
using namespace std;
class ABC_Base
{
public:
//pure virtual member function
//compelling effective creation of the
//function in the daughter classes
virtual int operate(int,int) = 0;
//virtual xtor as base will be derived
virtual ~ABC_Base() {}
};
class ABC_M1 : public ABC_Base
{
int operate (int a, int b ) {return a+b; }
};
class ABC_M2 : public ABC_Base
{
int operate (int a, int b ) {return a*b; }
};
ABC_Base * createABC(string xml_filename)
{
int criterion = 0;
// nullptr need at least c++11 option
ABC_Base * ptr = nullptr;
//read xml file and update criterion
//see other post to do that
//criterion = ...
switch(criterion)
{
case 0:
ptr = new ABC_M1();
break;
case 1:
ptr = new ABC_M2();
break;
default:
break;
}
return ptr;
}
int main()
{
ABC_Base * ptr = createABC("My_Config.xml");
if (nullptr != ptr)
{
cout << ptr->operate(3,4) << endl;
}
// If you absolutely want / have to use plain old pointers
// do not forget to release things
// works even if ptr is null, so unconditional delete
delete(ptr);
return 0;
}

Related

C++ polymorphism: how to create derived class objects

I have an abstract base class called BaseStrategy. It contains one pure virtual function calculateEfficiency(). There are two classes ConvolutionStrategy and MaxPoolStrategy which derive from this base class and implement their own specific version of calculateEfficiency().
Here is some code:
class BaseStrategy {
public:
explicit BaseStrategy();
virtual ~BaseStrategy() = default;
private:
virtual double calculateEfficiency(mlir::Operation* op) = 0;
};
class ConvolutionStrategy : public BaseStrategy {
private:
double calculateEfficiency(mlir::Operation* op)
{
//some formula for convolution
return 1;
}
};
class MaxPoolStrategy : public BaseStrategy {
private:
double calculateEfficiency(mlir::Operation* op)
{
//some formula for MaxPool
return 1;
}
};
Now I have another class called StrategyAssigner. It has method calculateAllLayerEfficiencies() whose purpose is to iterate over all layers in a network. Depending on the type of layer there is a switch statement and should call the correct calculateEfficiency() depending on the layer type.
class StrategyAssigner final {
public:
explicit StrategyAssigner(){};
public:
void calculateAllLayerEfficiencies() {
// Logic to iterate over all layers in
// a network
switch (layerType) {
case Convolution:
// Call calculateEfficiency() for Convolution
break;
case MaxPool:
// Call calculateEfficiency() for MaxPool
break;
}
};
}
int main ()
{
StrategyAssigner assigner;
assigner.calculateAllLayerEfficiencies();
}
My question is, should I store references of objects Convolution and MaxPool in the class StrategyAssigner so that I can call the respective calculateEfficiency().
Or could you suggest a better way to call calculateEfficiency(). I don't really know how to create the objects (stupid as that sounds).
I can't make calculateEfficiency() static as I need them to be virtual so that each derived class can implemented its own formula.
If you included complete code I could give a more detailed answer, but you need to store BaseStrategy pointers that are initialized with derived class instances. Here's an example made from some of your code:
std::vector<std::unique_ptr<BaseStrategy>> strategies;
strategies.emplace_back(new ConvolutionStrategy);
strategies.emplace_back(new MaxPoolStrategy);
for (int i = 0; i < strategies.size(); ++i) {
std::unique_ptr<BaseStrategy>& pStrat = strategies[i];
pStrat->calculateEfficiency(...);
}
Note that this won't compile because I don't have enough details from the code you posted to make it so, but this shows how to exploit polymorphism in the way that you need.
Also, I used smart pointers for memory management; use these at your discretion.
You can indeed use runtime polymorphism here:
Declare ~BaseStrategy virtual (you are already doing it ;-)
If you are never going to instantiate a BaseStrategy, declare one of its methods as virtual pure, e.g. calculateEfficiency (you are already doing it as well!). I would make that method const, since it doesn't look it's going to modify the instance. And it will need to be public, because it will need to be accessed from StrategyAnalyser.
Declare calculateEfficiency as virtual and override in each of the subclasses. It could also be final if you don't want subclasses to override it.
I'd keep a std::vector of smart pointers to BaseStrategy at StrategyAssigner. You can use unique_ptrs if you think this class is not going to be sharing those pointers.
The key point now is that you create heap instances of the subclasses and assign them to a pointer of the base class.
class StrategyAssigner final {
public:
void addStrategy(std::unique_ptr<BaseStrategy> s) {
strategies_.push_back(std::move(s));
}
private:
std::vector<std::unique_ptr<BaseStrategy>> strategies_{};
};
int main()
{
StrategyAssigner assigner;
assigner.addStrategy(std::make_unique<ConvolutionStrategy>());
}
Then, when you call calculateEfficiency using any of those pointers to BaseStrategy, the runtime polymorphism will kick in and it will be the method for the subclass the one that will be actually called.
class ConvolutionStrategy : public BaseStrategy {
private:
virtual double calculateEfficiency() const override {
std::cout << "ConvolutionStrategy::calculateEfficiency()\n";
return 10;
}
};
class MaxPoolStrategy : public BaseStrategy {
private:
virtual double calculateEfficiency() const override {
std::cout << "MaxPoolStrategy::calculateEfficiency()\n";
return 20;
}
};
class StrategyAssigner final {
public:
void calculateAllLayerEfficiencies() {
auto sum = std::accumulate(std::cbegin(strategies_), std::cend(strategies_), 0,
[](auto total, const auto& strategy_up) {
return total + strategy_up->calculateEfficiency(); });
std::cout << "Sum of all efficiencies: " << sum << "\n";
};
};
int main()
{
StrategyAssigner assigner;
assigner.addStrategy(std::make_unique<ConvolutionStrategy>());
assigner.addStrategy(std::make_unique<MaxPoolStrategy>());
assigner.calculateAllLayerEfficiencies();
}
// Outputs:
//
// ConvolutionStrategy::calculateEfficiency()
// MaxPoolStrategy::calculateEfficiency()
// Sum of all efficiencies: 30
[Demo]

Can you set pointer to derived class after you set some values in the base class?

I am new to c++ (I am using visual studio 2013) and I started experimenting with classes and inheritance. So I came up with a question which I can not find any anwser. Lets say we have this class:
#include <iostream>
using namespace std;
class base{
protected:
int var;
public:
void setvalue(int);
virtual void print();
};
class first:public base{
public:
void print();
};
class second: public base{
public:
void print();
};
Is there a way I can declare in my main() a pointer to base, set the value and after that choose if it is a first or second class? Ex:
int main(){
base *ptr = new base;
ptr->setvalue(1);
/* Here I choose if base is pointing to First or Second class*/
ptr->print(); // use the correct member, based on which class I choosed
return 0;}
Is this somehow possible? (As I said I am new to c++ so in case you have any questions, feel free to ask!)
Thanks!
Since it's not possible, the only thing that comes to mind is that you solve your problem in another way, perhaps using some well common design pattern.
In this case, given the little information you gave, Factory pattern seems appropriate.
#include <iostream>
using namespace std;
class base {
protected:
int var;
public:
void setvalue(int);
virtual void print();
static base* makeObject(int);
};
class first : public base {
public:
void print();
};
class second : public base {
public:
void print();
};
base* base::makeObject(int param) {
base* ret = NULL;
if(/* some condition based on params */) {
ret = new first();
ret->setvalue(0);
} else if(/* some other condition */) {
ret = new second();
ret->setvalue(1);
}
return ret;
}
int main() {
base *ptr = base::makeObject(...);
base->print(); // use the correct member, based on which class I choosed
return 0;
}
The type of an object is fixed at construction and can never be changed. So the direct answer to your question is "no".
But within that framework you have a lot of power. For example, you could separate your three classes out into four: three that do just do printing (BasePrinter, DerivedPrinter1, DerivedPrinter2) and other that just holds the value and doesn't have any virtual methods. Your BasePrinter class could get passed a ValueHolder object (by const reference) every time you call the print() method. Alternatively, each ValueHolder could have a pointer to BasePrinter object and pass in all the necessary data each time, with a little (non-virtual) print() method to do all this forwarding.
Not directly. When you create an object, you need to specify its full type so that C++ knows how to correctly lay out memory for you.
If you actually need to change it later, you can always create a new class (of the correct derived type) and use the original base class to initialize it, then delete the original. This might be slightly slower than the method you were proposing (depending on the final complexity of the class), but it would get the job done.
Since you are using inheritance , it is best practice to define virtual destructor in your base class. It will take care proper clean up when you define complicated class.
int main(){
base *ptr = new base;
base->setvalue(1);
/* Here I choose if base is pointing to First or Second class*/
base->print(); // use the correct member, based on which class I choosed
return 0;}
What you are trying to do is not possible. You have to change your program as follows to avoid compilation error.
base *ptr = new base;
ptr->setvalue(1);
ptr->print();
delete ptr;
return 0;
Because you base pointer ptr always have the dynamic type of class base. this code always invoke base::print function
If you define ptr as follows, you can utilize the polymorphism.
base * ptr = new first;
ptr->setvalue(1);
ptr-> print()
delete ptr
Here ptr has a dynamic type of class first and it will call function first::print()
You have to choose type at the creation of the object:
int main()
{
base *ptr = new first; // here.
ptr->setvalue(1);
ptr->print(); // use first::print.
delete ptr;
}

How to deal with "super" calls and recursion

My question is about merging 2 techniques:
Call recursively to super functions
Call recursively to the same function
Suppose a root class that has a recursive function (foo), and a extended class that override this function ( foo): the override function must call super::foo, but require to perform other operations before to call recursively.
I will try an example (it is only an example, and I know there is non-recursive way to solve this problem)
class Node
{
public:
// must be override
virtual int getNumValues()
{
if (parent) return parent->getNumValues() + 3;
else return 3;
}
protected:
Node *parent;
private:
int values[3];
};
class ExtNode: Node
{
public:
//#override
virtual int getNumValues()
{
int aux = Node::getNumValues(); //but need to avoid recursion here.
if (parent) return parent->getNumValues() + aux + 2;
else return aux + 2;
}
private:
int extValues[2];
};
So what I would is:
I may change both classes: Node and ExtNode.
I would not to copy the code from the first class method to the second to avoid Super call (the class chain may be long)
The recursive call should probably be done by the childest class
I am trying some ideas, but they seem poor programming practice or not possibles:
// In Node class
...
virtual int getNumValues()
{
if (parent && !isNodeObject(this)) return parent->getNumValues()+3;
else return 3;
}
bool isNodeObject( Node *ob)
{
//return if ob is instance of Node (and not an extended class). How?
}
I have also tried with optional parameters:
// In Node class
...
virtual int getNumValues( bool recursion = true)
{
if (parent && recursion) return parent->getNumValues()+3;
else return 3;
}
// In ExtNode class
...
virtual int getNumValues( bool recursion = true)
{
int aux = Node::getNumValues(false );
if (parent && recursion) return parent->getNumValues() + aux + 2;
else return aux + 2;
}
What is the best programming practice for that?
EDIT 1: Explanation of the real problem I am trying to resolve (asked from Joachim Pileborg)
I am creating a User interface library, that is, a set of classes and function to create easily widgets like frame, buttons, input texts, etc.
I have created a basic (root class) widget with most general features, a "Visible" widget to implement all generic functions for widgets that has a visible part, and soo on.
There are also some containers, like frames, layout and windows.
Now come the hard part: there is a function "updateStyle" that is supposed to update at once all the graphic part of the widget (and redraw it): this function call recursively to super class to perform more generic features, and also has to call recursively to containers to propagate changes (dimensions and positions of widgets may change)
Each widget is supposed to work "as this" and also to be extendable, that is why these requirements.
Code is extensive (about 8k lines) and has a lot of other features, so no point to copy here
the code.
It looks like you are searching for the template method pattern:
in the base class, implement a nonvirtual method that outlines the general behavior of the function.
define (abstract) virtual methods that define the special behavior parts inside that function
in derived classes, override the special behavior
class Node
{
public:
int getAllNumValues()
{
int allNumValues = getNumValues();
if (parent) allNumValues += parent->getAllNumValues();
return allNumValues;
}
protected:
virtual int getNumValues() {
return 3;
};
private:
Node *parent;
int values[3];
};
class ExtNode: Node
{
protected:
//#override
virtual int getNumValues()
{
return 2 + Node::getNumValues(); //but need to avoid recursion here.
}
private:
int extValues[2];
};
in case of your update functionality I'd suggest to have a template method update that does the recursive updating of your composite pattern, and another method updateThis that does updating of only the single object.
According to Herb Sutter's article: Virtuality, we should prefer to make virtual functions private. This implies that we should try to avoid calling "super" versions and instead make the base class do the work.
Here's an example:
class Node
{
public:
int getNumValues()
{
int result = 3 + DoGetNumValues();
if (parent)
result += parent->getNumValues();
return result;
}
private:
Node *parent;
int values[3];
virtual int DoGetNumValues() {return 0;}
};
class ExtNode : public Node
{
private:
int extValues[2];
int DoGetNumValues() override sealed {return 2 + GetMoreValues();}
virtual int GetMoreValues() {return 0;}
};
class Derived : public ExtNode
{
int GetMoreValues() override {return 1;}
};
For the first example,
Node::getNumValues() computes some function of a tree.
ExtNode::getNumValues() computes another function of a tree. Either result of
ExtNode::getNumValues() is function of ( Node::getNumValues(), tree ) or it depends on tree only.
For UI problem,
Think about chain of responsibility design pattern. Forward update request up to the root node, which in its turn initiates tree traversal to update all nodes starting from root.
One way to deal with this is to make the function non virtual, then explicitly call in each override the super classe's function (similar to the constructor).
Having the method non-virtual means that each class that is inherited will have it's own implementation of the method, so you won't overwrite the classe's parent code by writing a implementation of the function.
The downside will be that you will have to call the function via a pointer that is explicitly of a certain type, thus forcing you to know the type.
To avoid this drawback, make a virtual function that calls the required recursive function, and use that function instead.
As a side note, non-virtual functions should be avoided.
Here's a sample code
class base
{
public:
int doStuff()
{
printf(" base called ");
return 0;
}
};
class ext : public base
{
public:
int doStuff()
{
base::doStuff();
printf(" ext called ");
return 0;
};
};
class ext2 : public ext
{
public:
int doStuff()
{
ext::doStuff();
printf(" ext 2 called");
return 0;
};
};
void runTest()
{
base* ptr = new ext2();
ptr->doStuff();
ext2* recast = (ext2*) ptr;
recast->doStuff();
}
For the code above, the output will be " base called base called ext called ext2 called".
If you declare the doStuff function virtual in the base class (thus making it virutal for every child class) the output will be " base called ext called ext2 called base called ext called ext2 called".

polymorphism and encapsulation of classes

I'm trying to take advantage of the polymorphism in c++, but I'm from a c world, and I think what I've done could be done more cleverly in a OOP way.
I have 2 classes that has exactly the same public attributes, and I want to "hide" that there exists 2 different implementations. Such that I can have a single class where I can use the member functions as If i were accessing the specific class.
An very simple implementation of what I'm trying to accomplish is below:
#include <iostream>
class subber{
private:
int id;
public:
int doStuff(int a,int b) {return a-b;};
};
class adder{
private:
int id;
public:
int doStuff(int a, int b) {return a+b;};
};
class wrapper{
private:
int type_m;
adder cls1;
subber cls2;
public:
wrapper(int type) {type_m=type;};//constructor
int doStuff(int a, int b) {if(type_m==0) return cls1.doStuff(a,b); else return cls2.doStuff(a,b);};
};
int main(){
wrapper class1(0);
std::cout <<class1.doStuff(1,3) <<std::endl;
wrapper class2(1);
std::cout <<class2.doStuff(1,3) <<std::endl;
return 0;
}
I have 2 classes called "subber" and "adder" which both have a member function called doStuff, which will either subtract of add 2 numbers.
This I wrap up in a class "wrapper", which has both "adder" and "subber" as private variables, and a doStuff public member function. And given which value I instantiate my "wrapper" class with, my "wrapper" class will simply relay the "doStuff" to the correct class.
This code does of cause work, but I would like to avoid instatiating both "subber" and "adder" in my wrapper class, since I will only need of them in each of my "wrapper" classes.
Thanks
There are many ways to do it. Through a Factory for example.
But to keep it simple - make a base abstract class that defines the interface, and derive your classes from it to implement the functionality. Then you only need to make the distinction once, when you create the class, after that you don't care, you just call the interface functions.
your code would look something like that.
class DoStuffer
{
public:
virtual int doStuff(int, int)=0;
virtual ~DoStuffer(){}; // Because Tony insists:-) See the comments
}
class subber: public DoStuffer{
public:
virtual int doStuff(int a,int b) {return a-b;};
};
class adder: public DoStuffer{
public:
virtual int doStuff(int a, int b) {return a+b;};
};
int main(){
DoStuffer *class1 = new adder();
DoStuffer *class2 = new subber();
std::cout <<class1->doStuff(1,3) <<std::endl;
std::cout <<class2->doStuff(1,3) <<std::endl;
delete class1; // don't forget these:-)
delete class2;
return 0;
}
This is one of the more idiomatic ways to use the C++ class system to accomplish what you want. Both adder and subber publicly inherit from wrapper, which is now an abstract base class. The doStuff method is now a (pure) virtual function. And instead of being a simple instance of wrapper, the "encapsulated" object is now a reference to a wrapper.
#include <iostream>
class wrapper {
public:
virtual int doStuff(int a, int b) = 0;
};
class subber : public wrapper {
public:
virtual int doStuff(int a,int b) {return a - b;}
};
class adder : public wrapper {
public:
virtual int doStuff(int a, int b) {return a + b;}
};
int main(){
// actual objects
adder impl1;
subber impl2;
// in real code, the wrapper references would probably be function arguments
wrapper& class1 = impl1;
std::cout << class1.doStuff(1,3) << std::endl;
wrapper& class2 = impl2;
std::cout << class2.doStuff(1,3) << std::endl;
return 0;
}
(Not using any factory pattern in this example, since it's not obvious that it's needed or what the question is about.)
Exactly what was last said.
Make a base class, and have a virtual function |doStuff| in it.
Then you can derive any number of classes out from it, all have to implement the above virtual function, in whatever way they want to.
Then you can just do the following
BaseClass *object1 = new DerivedClass1();
BaseClass *object2 = new DerivedClass2();
..
You can even do
object1 = object2;
And then they point to the same object (i.e. an object of type |DerivedClass2|)
But remember, when you do objectn->doStuff(), the function that will be executed will be what the pointer points to at run-time, and not at compile time.
i.e. if I do object1->doStuff() DerivedClass2's doStuff will be called because we already did `object1 = object2;
You may want to Google and read about
Polymorphism/ Run-time Polymorphism
Virtual Functions in C++
You can read Factory Method, which is something that is known as a Design Pattern, but later in life.
Thanks
The classic run-time polymorphic approach is:
struct Operation
{
virtual ~Operation() { } // guideline: if there are any virtual functions,
// provide virtual destructor
virtual int doStuff(int, int) const;
};
struct Subber : Operation
{
int doStuff(int a, int b) const { return a - b; }
};
struct Adder : Operation
{
int doStuff(int a, int b) const { return a + b; }
};
enum Operations { Add, Subtract };
struct Operation* op_factory(Operations op)
{
if (op == Add) return new Adder;
if (op == Subtract) return new Subber;
throw std::runtime_error("unsupported op");
}
int main()
{
Operation* p1 = op_factory(Add);
std::cout << p1->doStuff(1,3) <<std::endl;
Operation* p2 = op_factory(Subtract);
std::cout << p2->doStuff(1,3) <<std::endl;
delete p1;
delete p2;
}
From the Standard 5.3.5/5 "In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand's dynamic type and the static type shall have a virtual destructor or the behavior is undefined.", which is why you must use the virtual keyword on the base class destructor.
It's noteworthy that in your example the type of operation to perform was communicated to the wrapper class using a function argument of 0 or 1... this is what suggests you want run-time polymorphism. For example, if the 0 or 1 value was based on a command line argument, file content, keyboard input etc., then the factory method above can pass a corresponding Add or Subtract value and receive an appropriately-behaving object derived from Operation. This concept of creating an instance of a run-time polymorphic type based on run-time values is known as a factory.
If you really only need compile-time polymorphism, you can do some interesting things with templates such as:
template <class Operation>
void output(int a, int b)
{
std::cout << Operation::doStuff(a, b) << std::endl;
std::cout << Operation::doStuff(a * 10, b * 10) << std::endl;
std::cout << Operation::doStuff(a * 100, b * 100) << std::endl;
}
int main()
{
output<adder>(1, 3);
output<subber>(1, 3);
}
FWIW, your approach is probably slightly faster than the virtual function approach (as it can potentially do more inlining), but not as clean, extensible, maintainable or scalable.
I think what you're looking for is virtual functions. If you declare a function virtual in your base class, you can do things like make a vector containing multiple objects derived from your base class, but when you call on a particular object it will execute it's own method.

Avoiding dynamic_cast in implementation of virtual functions in derived class

Here is some sample code explaining what I am trying to achieve.
Basically, I have an algorithm that depends on some basic operations available in a class. I have defined those operations in a pure abstract base class. I want to apply that algorithm to a variety of objects that provide those operations by deriving classes for the specific objects.
However, the different derived objects are incompatible with one another as far those operations are concerned. My question is whether I can avoid using RTTI to ensure that for example, bool derived2::identical(const base* other2), asserts(or other exit mechanism) where other2 is not of type derived2.
One alternative would be to template the function algorithm on the specific derived object, but that would mean that it's implementation would have to live in a header file which I don't want to do since 1) Changing the algorithm code for test purposes can cause recompilation of large portions of the code 2) The algorithm's implementation would be exposed in the header instead of living nicely in a source file hidden from the end-user.
Header file
#include <list>
class base
{
public:
virtual float difference(const base*) const = 0;
virtual bool identical(const base*) const = 0;
};
class derived1 : public base
{
public:
float difference(const base* other1) const
{
// other1 has to be of type derived1
if(typeid(other1) == typeid(this))
{
// process ...
}
else
{
assert(0);
}
return 1;
}
bool identical(const base* other1) const
{
// other1 has to be of type derived1
if(typeid(other1) == typeid(this))
{
// compare...
}
else
{
assert(0);
}
return true;
}
};
class derived2 : public base
{
public:
float difference(const base* other2) const
{
// process ...
// other2 has to be of type derived2
return 2;
}
bool identical(const base* other2) const
{
// do comparison
// derived1 and derived2 cannot be compared
return true;
}
};
// Declaration
int algorithm(std::list<base*>& members);
Implementation of algorithm Source file
#include "header_file_containing_base"
int algorithm(std::list<base*>& members)
{
// This function only relies on the interface defined in base
// process members;
return 1;
}
Main program
int main()
{
// Create lists of derived1 and derived2
// Run algorithm on these lists
}
You could use double dispatch (http://en.wikipedia.org/wiki/Double_dispatch)
Well, there is one simple thing: store the real type as a member.
An enum, grouping all the types. It'll become cumbersome if you have a lot of them.
A Factory to generate ids (using templates to only generate one id per item)
...
I'll illustrate the factory id:
class IdFactory
{
public:
template <class T>
static size_t GetId(T const&) // argument deduction
{
static size_t const Id = GetIdImpl();
return Id;
}
private:
static size_t GetIdImpl()
{
static size_t Id = 0;
return ++Id;
}
}; // class IdFactory
And you can use it like such:
class Base
{
public:
explicit Base(size_t id): mId(id) {}
size_t const mId; // meaningless to change it afterward...
private:
};
class Derived: public Base
{
public:
explicit Derived(): Base(IdFactory::GetId(*this)) {}
};
Then you can use the mId member for testing. Note that since it's const it can be exposed... otherwise you can create an inline const getter...
float Derived::difference(const Base& rhs)
{
assert( IdFactory::GetId(*this) == rhs.mId );
// ...
}
The cost here is negligible:
GetId is inlined, thus no function call
GetId is lazily initialized, apart for the initialization it amounts to checking that the static member has been initialized: it's typically implemented as a if statement which condition always evaluate to true (apart from the first time).
== is normally fast ;)
The only downside is that you actually need to make sure that you correctly initialize the ids.
There is also a no-storing solution, which involves a virtual function call:
class Other: public Base
{
public:
virtual size_t id() const { return IdFactory::GetId(*this); }
};
It's easier to put in practice because not storing a const member means that you don't have to write the assignment yourself.
You could use a templated function. With templates it is possible to add more classes later without the need to change the original classes, by just adding another template function in another header file. If the only problem is the compile speed - you can implement the template function in a source file apart from the header and use explicit template instanciation.