Derived class dependent function - c++

I have base class DataProcessor. It is base class for calculators of position in some coordinate system. So, for example, it can have descendants like: SphericDataProcessor, CartesianDataProcessor. There is base class CookedDataCatalogue, which is base class for containers of some objects' positions. So every DataProcessor should be able put its data to every CookedDataCatalogue. I can imagine something like this:
class CookedDataCatalogue
{
virtual void Transform(DataProcessor* dp) = 0;
virtual void PutData(???) = 0;
}
class CookedDataCatalogue1 : public CookedDataCatalogue
{
void Transform(DataProcessor* dp) override
{
dp->TransformTo(this);
}
}
class CookedDataCatalogue2 : public CookedDataCatalogue
{
...
}
class CookedDataCatalogue3 ...
class DataProcessor
{
virtual void Process() = 0;
virtual void TransformTo(CookedDataCatalogue1* c) = 0;
virtual void TransformTo(CookedDataCatalogue2* c) = 0;
virtual void TransformTo(CookedDataCatalogue3* c) = 0;
}
But I don't like it. First of all void Transform(DataProcessor*) migrates from base class to all children**. Second, if I build it as library, other user can not add his own CookedDataUserCatalogue, because he can't add another void TransformTo(CookedDataUserCatalogue). Third, I don't know how to write function PutData(), because every Catalogue uses his own data to contain. Should it be templated?
What is a solution? Is there any programming pattern that I missed?

There are two ways to do this as well as the Double Dispatch Pattern mentioned in the comments:
Baseline
The first is that you specify a "baseline" set of co-ordinates. In order to convert first you transform to the core set and then you transform from that.
Advantages: You only need to write a toBaseline and fromBaseline for any number of different DataProcessors. Adding a new DataProcessor is as simple as creating it and then writing the transformation to and from the core set.
Disadvantages: Performance will suffer as you do two transformations in most cases. Accuracy may suffer due to losses either in representation or conversion.
Transformer objects
Create an interface that converts an object from DataProcessor to DataProcessor.
Create an instance of that interface for each supported transformation.
Have a utility class that has a map of source and destination pairs to the correct transform to use. Call a method on that utility class to perform the transformation on demand.
Advantages: No wastage from having to do multiple transformations.
Disadvantages: n^2 Transform objects need creating where n is the number of different DataProcessor objects. When creating a new DataProcessor you will need to write and add Transform objects for each DataProcessor added. Missing Transforms will be detected at run time not compile time.

Related

c++ particle system inheritance

i'm creating particle system and i want to have possibility to choose what kind of object will be showing on the screen (like simply pixels, or circle shapes). I have one class in which all parameters are stored (ParticleSettings), but without those entities that stores points, or circle shapes, etc. I thought that i may create pure virtual class (ParticlesInterface) as a base class, and its derived classes like ParticlesVertex, or ParticlesCircles for storing those drawable objects. It is something like that:
class ParticlesInterface
{
protected:
std::vector<ParticleSettings> m_particleAttributes;
public:
ParticlesInterface(long int amount = 100, sf::Vector2f position = { 0.0,0.0 });
const std::vector<ParticleSettings>& getParticleAttributes() { return m_particleAttributes; }
...
}
and :
class ParticlesVertex : public ParticlesInterface
{
private:
std::vector<sf::Vertex> m_particleVertex;
public:
ParticlesVertex(long int amount = 100, sf::Vector2f position = { 0.0,0.0 });
std::vector<sf::Vertex>& getParticleVertex() { return m_particleVertex; }
...
}
So... I know that i do not have access to getParticleVertex() method by using polimorphism. And I really want to have that access. I want to ask if there is any better solution for that. I have really bad times with decide how to connect all that together. I mean i was thinking also about using template classes but i need it to be dynamic binding not static. I thought that this idea of polimorphism will be okay, but i'm really need to have access to that method in that option. Can you please help me how it should be done? I want to know what is the best approach here, and also if there is any good answer to that problem i have if i decide to make that this way that i show you above.
From the sounds of it, the ParticlesInterface abstract class doesn't just have a virtual getParticleVertex because that doesn't make sense in general, only for the specific type ParticlesVertex, or maybe a group of related types.
The recommended approach here is: Any time you need code that does different things depending on the actual concrete type, make those "different things" a virtual function in the interface.
So starting from:
void GraphicsDriver::drawUpdate(ParticlesInterface &particles) {
if (auto* vparticles = dynamic_cast<ParticlesVertex*>(&particles)) {
for (sf::Vertex v : vparticles->getParticleVertex()) {
draw_one_vertex(v, getCanvas());
}
} else if (auto* cparticles = dynamic_cast<ParticlesCircle*>(&particles)) {
for (CircleWidget& c : cparticles->getParticleCircles()) {
draw_one_circle(c, getCanvas());
}
}
// else ... ?
}
(CircleWidget is made up. I'm not familiar with sf, but that's not the point here.)
Since getParticleVertex doesn't make sense for every kind of ParticleInterface, any code that would use it from the interface will necessarily have some sort of if-like check, and a dynamic_cast to get the actual data. The drawUpdate above also isn't extensible if more types are ever needed. Even if there's a generic else which "should" handle everything else, the fact one type needed something custom hints that some other future type or a change to an existing type might want its own custom behavior at that point too. Instead, change from a thing code does with the interface to a thing the interface can be asked to do:
class ParticlesInterface {
// ...
public:
virtual void drawUpdate(CanvasWidget& canvas) = 0;
// ...
};
class ParticlesVertex {
// ...
void drawUpdate(CanvasWidget& canvas) override;
// ...
};
class ParticlesCircle {
// ...
void drawUpdate(CanvasWidget& canvas) override;
// ...
};
Now the particles classes are more "alive" - they actively do things, rather than just being acted on.
For another example, say you find ParticlesCircle, but not ParticlesVertex, needs to make some member data updates whenever the coordinates are changed. You could add a virtual void coordChangeCB() {} to ParticlesInterface and call it after each motion model tick or whenever. With the {} empty definition in the interface class, any class like ParticlesVertex that doesn't care about that callback doesn't need to override it.
Do try to keep the interface's virtual functions simple in intent, following the Single Responsibility Principle. If you can't write in a sentence or two what the purpose or expected behavior of the function is in general, it might be too complicated, and maybe it could more easily be thought of in smaller steps. Or if you find the virtual overrides in multiple classes have similar patterns, maybe some smaller pieces within those implementations could be meaningful virtual functions; and the larger function might or might not stay virtual, depending on whether what remains can be considered really universal for the interface.
(Programming best practices are advice, backed by good reasons, but not absolute laws: I'm not going to say "NEVER use dynamic_cast". Sometimes for various reasons it can make sense to break the rules.)

Avoiding performance concerns of Runtime Polymorphism

In a numerical code run on thousands of processors for 10s of hours, I have a base class (Mesh) whose methods are hit 100s to 1000s of millions of times. There are currently two (Mesh_A, Mesh_B) derived classes, but eventually this will expand to three or four. User code cannot know until runtime whether its pointer to Mesh is actually a Mesh_A or Mesh_B, but for the rest of the run, it never changes.
Current Implementation:
// Base class
class Mesh {
...
virtual const Point& cell_centroid(int c) = 0;
}
// derived class A
class MeshA : public Mesh {
...
Point& cell_centroid(int c) { return cell_centroids_[c]; }
}
// derived class B
class MeshB : public Mesh {
...
Point& cell_centroid(int c) { return other_framework_->cell_centroid(c); }
}
// typical user class
class User {
User(Mesh* mesh) : mesh_(mesh) {}
void evalFunction() {
for (int c=0; c!=mesh_->num_cells(); ++c) {
double result = func(mesh_->cell_centroid(c));
...
}
}
// Other methods which use mesh_->cell_centroid() very often, and in different ways.
}
Previously, MeshA was the only Mesh, and there was no base class, and the heavily hit methods were all inlined. Profiling shows that the change to runtime polymorphism (likely thanks to the loss of inlining?) with virtual methods has resulted in a ~15% hit, which just isn't going to fly.
I've been pouring over static polymorphism and other ideas, but I'd love to hear thoughts on how one might avoid this hit in a reasonably sustainable way.
Idea 1: Coarsen the virtual function to amortize overhead. One thought was to try to encapsulate all the "calling patterns" of these methods inside a virtual method, lifting the virtual to a coarser level while keeping the fine-grained methods as non-virtual. For example, in the above example, one could pass a function pointer to a new virtual method of Mesh that implemented the loop, returning an array of doubles and called a non-virtual, inlined cell_centroid() method inside of this.
// Base class
class Mesh {
...
virtual void evalFunction(double (*func)(Point&), std::vector<double>* result) = 0;
}
// derived class A
class MeshA : public Mesh {
...
void evalFunction(double (*func)(Point&), std::vector<double>* result) {
for (int c=0; c!=num_cells(); ++c) (*result)[c] = (*func)(cell_centroid(c));
}
Point& cell_centroid(int c) { return cell_centroids_[c]; }
}
// similar for B
// typical user class
class User {
User(Mesh* mesh) : mesh_(mesh) {}
void evalFunction() {
m_->evalFunction();
}
}
I'm a little nervous that this will make the Mesh interface huge -- I don't have a single access pattern (like the example) that could easily be encapsulated. My guess is that, for every virtual method in the current Mesh class (15-20), I'd have 3 or 4 different "calling patterns", and the interface for Mesh would explode. There are a variety of "User" classes and, while the sometimes use Mesh the same way, they don't always, and I don't want to limit myself to a few patterns.
Idea 2: Template all user code with Mesh_T. Write a factory that creates User<MeshA> or User<MeshB> instances depending upon runtime information. This is a little concerning because this will effectively mean that my entire code is templated code, compile times will blow up, errors will be harder to debug etc. A large code base would be touched.
Idea 3: It seems to me that one ought to be able to resolve, at the start of the run, that the Mesh pointer User gets is actually a MeshA or MeshB, and not need to do the virtual table lookups and regain the inlined A or B implementation. I don't know of an elegant way of doing this that wouldn't basically be worse than Idea 1, i.e. a bunch of duplicated code in User with case/switch. But if there were an elegant way of doing this, it would be my first choice.
Any thoughts on a good choice, a better idea, or other comments on runtime polymorphism of a high level class without virtual low-level methods would be appreciated!
Provided I understood you correctly that mesh_ will always be either MeshA or MeshB and not a mix of them.
// typical user class
class User {
User(Mesh* mesh) : mesh_(mesh) {}
template<class dType>
void evalFunction() {
dType *myMesh = dynamic_cast<dType *>(mesh_);
for (int c=0; c!=myMesh _->num_cells(); ++c) {
double result = func(myMesh _->cell_centroid(c));
...
}
}
void evalFunction() {
if (dynamic_cast<MeshA *>(mesh_))
evalFunction<MeshA>();
if (dynamic_cast<MeshB *>(mesh_))
evalFunction<MeshB>();
}
}
evalFunction chooses either A or B template.
Alternatively
class User {
User(Mesh* mesh) : mesh_(mesh) {}
template<class dType>
void evalFunction(dType *myMesh) {
for (int c=0; c!=myMesh _->num_cells(); ++c) {
double result = func(myMesh _->cell_centroid(c));
...
}
}
void evalFunction() {
MeshA *meshA = dynamic_cast<MeshA *>(mesh_);
if (meshA)
evalFunction<MeshA>(meshA);
MeshB *meshB = dynamic_cast<MeshB *>(mesh_);
if (meshB)
evalFunction<MeshB>(meshB);
}
}

Creating classes to represent different permutations of a type

Suppose I have a class structure like (simplifying the actual classes I have):
class Graph
{
};
class DerivedGraph : public Graph
{
};
class DerivedGraph2 : public Graph
{
};
I want to expand this structure to account for different variations of the same graph. Ideally I would like to be able to do something like:
class Graph
{
};
// Removed
//class DerivedGraph : public Graph
//{
//};
// Removed
//class DerivedGraph2 : public Graph
//{
//};
class DerivedGraph3 : public Graph // really just a mode of DerivedGraph
{
};
class DerivedGraph4 : public Graph // really just a second mode of DerivedGraph
{
};
class DerivedGraph5 : public Graph // really just a mode of DerivedGraph2
{
};
class DerivedGraph6 : public Graph // really just a second mode of DerivedGraph2
{
};
But you can quickly see the problem here -- I am having to create too many classes here. Also, the base class is extremely complex and large (the bottom line is that it just plain sucks) ... so I don't want to make too many structural changes. I want the flexibility of defining things at the level of just the graph itself but at the same time have the flexibility of defining things for a particular mode of one graph type. I would like to be able to use virtual functions such as DoesGraphSupportNormalizedData() or something like that (this is just a simple example). Each class would then override this method.
Another idea I had was to create a separate class structure for the modes themselves (the Graph class would create an instance of it), like:
class BaseMode
{
};
class Mode1 : public BaseMode
{
};
class Mode2 : public BaseMode
{
};
Now the problem is that these mode classes need access to several pieces of data from the Graph class ... and I really don't want to pass all of that information. The mode class would then become just as useless and wouldn't be flexible at all. I just can't think of a clean way to deal with this. The best I could come up with is to have the mode classes do what it can without having to pass all kinds of crap to it but now the interface is just goofy and awkward. Any ideas?
You can either user and interface or use inherited classes from what I can gather from your description.
If you use a base-class and inherit off of it just have the things you don't want derived classes to have just give them the private access modifier and then protected or public for the others (depending on the situation of course). That way your derived classes only take what information they need. You could also have a instance variable that needs to be set in each of lower classes to define things about each derived class. Access modifiers are your friends.
If you use an interface just include everything each graph will need and then when building the individual classes just customize them from there to include the specialties.
If it were up to me, personally, I would go with inheritance over an interface but that's just me.
I ran in this kind of a problem before (and still now and then...)
In this case, you may be taking it the wrong way, what you're looking into is device a specialized function depending on the type of graph and mode. Inheritance is nice, but it has its limits as you mentioned. Especially because the user may want to switch the type of graph, but keep is existing graph object. Inheritance is not helpful in that case.
One way to do something like this is to create functions that get called depending on the current type and mode. Say you have to draw lines and the mode can be set to LINE or DOTS. You could have two functions that draw a line and are specific to a mode or another:
void Graph::draw_line_line(line l)
{
// draw a line
}
void Graph::draw_line_dots(line l)
{
// draw a dots along the line
}
Now you can define a type which represents that type of render functions and a variable member for it:
typedef void (Graph::*draw_line_func)(line l);
draw_line_func m_draw_line;
With that in hands, you can program your set_mode() function, something like this:
void Graph::set_mode(mode_t mode)
{
m_mode = mode; // save for get_mode() to work
switch(mode)
{
case LINE:
m_draw_line = &Draw::draw_line_line;
break;
case DOTS:
m_draw_line = &Draw::draw_line_dots;
break;
...
}
}
Now when you want to render the line, you do call this specialized function and you do not need to know whether it is a LINE or a DOTS...
void Graph::draw_line(line l)
{
this->*m_draw_line(l);
}
This way you create an indirection and make it a lot cleaner in the existing large functions that have large switch or many if() statements without breaking up the existing "powerful" class in many pieces that may become hard to use (because if it's that big it's probably already in use...)

Creating a new object by calling the new constructor with a string

I was recently in a job interview and my interviewer gave me a modeling question that involved serialization of different shapes into a file.
The task was to implements shapes like circle or rectangles by first defining an abstract class named Shape and then implements the various shapes (circle, rectangle..) by inheriting from the base class (Shape).
The two abstract methods for each shape were: read_to_file (which was supposed to read the shape from a file) and write_to_file which supposed to write the shape into a file.
All was done by the implementation of that virtual function in the inherited shape (Example: For Circle I was writing the radius, for square I saved the side of the square....).
class Shape {
public:
string Shape_type;
virtual void write_into_file()=0;
virtual void read_into_files()=0;
Shape() {
}
virtual ~Shape() {
}};
class Square: public Shape {
public:
int size;
Square(int size) {
this->size = size;
}
void write_into_file() {
//write this Square into a file
}
void read_into_files() {
//read this Square into a file
}
};
That was done in order to see if I know polymorphism.
But, then I was asked to implement two functions that take a vector of *shape and write/read it into a file.
The writing part was easy and goes something like that:
for (Shape sh : Shapes) {
s.write_into_file();
}
as for the reading part I thought about reading the first word in the text (I implemented the serializable file like a text file that have this line: Shape_type: Circle, Radius: 12; Shape_type:Square...., so the first words said the shape type). and saving it to a string such as:
string shape_type;
shape_type="Circle";
Then I needed to create a new instance of that specific shape and I thought about something like a big switch
<pre><code>
switch(shape_type):
{
case Circle: return new circle;
case Square: return new square
......
}
</pre></code>
And then, the interviewer told me that there is a problem with this implementation
which I thought was the fact that every new shape the we will add in the future we should also update int that big swicht. he try to direct me into a design pattern, I told him that maybe the factory design pattern will help but I couldn't find a way to get rid of that switch. even if I will move the switch from the function into a FactoryClass I will still have to use the switch in order to check the type of the shape (according to the string content i got from the text file).
I had a string that I read from the file, that say the current type of the shape. I wanted to do something like:
string shape_type;
shape_type="Circle";
Shape s = new shape_type; //which will be like: Shape s = new Circle
But I can't do it in c++.
Any idea on what I should have done?
In you factory you could map a std::string to a function<Shape*()>. At startup you register factory methods will the factory:
shapeFactory.add("circle", []{new Circle;});
shapeFactory.add("square", []{new Square;});
shapeFactory.add("triangle", []{new Triangle;});
In your deserialization code you read the name of the type and get its factory method from the factory:
std::string className = // read string from serialization stream
auto factory = shapeFactory.get(className);
Shape *shape = factory();
You've now got a pointer to the concrete shape instance which can be used to deserialize the object.
EDIT: Added more code as requested:
class ShapeFactory
{
private:
std::map<std::string, std::function<Shape*()> > m_Functions;
public:
void add(const std::string &name, std::function<Share*()> creator)
{
m_Functions.insert(name, creator)
}
std::function<Shape*()> get(const std::string &name) const
{
return m_Functions.at(name);
}
};
NOTE: I've left out error checking.
In C++, with
for (Shape sh : Shapes) {
s.write_into_file();
}
you have object slicing. The object sh is a Shape and nothing else, it looses all inheritance information.
You either need to store references (not possible to store in a standard collection) or pointers, and use that when looping.
In C++ you would to read and write some kind of type tag into the file to remember the concrete type.
A virtual method like ShapeType get_type_tag() would do it, where the return type is an enumeration corresponding to one of the concrete classes.
Thinking about it, though, the question was probably just getting at wanting you to add read and write functions to the interface.
You could create a dictionary of factory functions keyed by a shape name or shape id (shape_type).
// prefer std::shared_ptr or std::unique_ptr of course
std::map<std::string, std::function<Shape *()>> Shape_Factory_Map;
// some kind of type registration is now needed
// to build the map of functions
RegisterShape(std::string, std::function<Shape *()>);
// or some kind of
BuildShapeFactoryMap();
// then instead of your switch you would simply
//call the appropriate function in the map
Shape * myShape = Shape_Factory_Map[shape_type]();
In this case though you still have to update the creation of the map with any new shapes you come up with later, so I can't say for sure that it buys you all that much.
All the answers so far still appear to have to use a switch or map somewhere to know which class to use to create the different types of shapes. If you need to add another type, you would have to modify the code and recompile.
Perhaps using the Chain of Responsibility Pattern is a better approach. This way you can dynamically add new creation techniques or add them at compile time without modifying any already existing code:
Your chain will keep a linked list of all the creation types and will traverse the list until it finds the instance that can make the specified type.
class Creator{
Creator*next; // 1. "next" pointer in the base class
public:
Creator()
{
next = 0;
}
void setNext(Creator*n)
{
next = n;
}
void add(Creator*n)
{
if (next)
next->add(n);
else
next = n;
}
// 2. The "chain" method in the Creator class always delegates to the next obj
virtual Shape handle(string type)
{
next->handle(i);
}
);
Each subclass of Creator will check if it can make the type and return it if it can, or delegate to the next in the chain.
I did create a Factory in C++ some time ago in which a class automatically registers itself at compile time when it extends a given template.
Available here: https://gist.github.com/sacko87/3359911.
I am not too sure how people react to links outside of SO but it is a couple of files worth. However once the work is done, using the example within that link, all that you need to do to have a new object included into the factory would be to extend the BaseImpl class and have a static string "Name" field (see main.cpp). The template then registers the string and type into the map automatically. Allowing you to call:
Base *base = BaseFactory::Create("Circle");
You can of course replace Base for Shape.

How can I switch element and container types for purpose of benchmarking, without producing a large number of test client applications?

I have a ClientInterface class, that uses the Strategy pattern to organize two complex algorithms conforming to interfaces Abase and Bbase, respectively. The ClientInterface agglomerates (via composition) the data on which the algorithms operate, which needs to conform to the Data interface.
What I tried to do is to have a single ClientInterface class, which is able to choose different Strategies and Data implementations at run-time. The algorithms and data implementations are chosen using the Factory Method which reads the strings from an input file and selects the algorithm and data implementation in the ClientInterface constructor. The run-time choice of data and algorithms is not provided in the code model below.
The Data implementation can be based on a map, a list, an unordered_map , etc. to test how does the efficiency of two complex algorithms (Abase and Bbase implemented Strategies) change with different containers used for the Data.
Additionally, the Data agglomerates different Elements (ElementBase implementations). Different element implementations will also have significant impact on the efficiency of theh ClientInterface, but the Elements are really disjoint types with implementations coming from different libraries. I know this for a fact, since profiling the existing application shows the Element operation to be one of the bottlenecks.
I know that if I use polymorphism with containers, there is "boost/ptr_container" out there, but the Data will store hundreds of thousands, if not millions of Elements. Using polymorphism for Elements in this case will have a significant overhead on the ClientInterface, but if I choose to make data a class Template for the Element type, I will end up statically defining the ClientInterface class, which means producing a client application per each Element type at least.
Can I assume that for the same number of Elements and the ClientInterface configuration obtained at run-time, the overhead induced by the use of polymorphism for the Element type will have the same impact on all configurations of the Data and Algorithm implementations? In this case, I can run the automated tests, decide on the configuration of the Data implementation and the Element implementation, and define a statically configured EfficientClientInterface to be used in the productive code?
Goal: I have a test harness prepared, and what I am trying to do is to automatize the testing on the family of test cases, since changing the Algorithms and Elements at run-time, allows me to use a single application in a loop, which is configured at run-time and whose output is measured for efficiency. In the real implementation, I am dealing with at least 6 algorithm interfaces, 3-4 Data implementations, and I estimate 3 Element implementations at least.
So, my questions are:
1) How can an Element support different operations when overloading is not working for return types? If I make the operation a template, it needs to be defined at compile-time, which messes with my automated testing procedure.
2) How can I design this code better to achieve the goal?
3) Is there a better overall approach to this problem?
Here is the code model:
#include <iostream>
#include <memory>
class ElementOpResultFirst
{};
class ElementOpResultSecond
{};
class ElementBase
{
public:
// Overloading does not allow different representation of the solution for the element operation.
virtual ElementOpResultFirst elementOperation() = 0;
//virtual ElementOpResultSecond elementOperation() = 0;
};
class InterestingElement
:
public ElementBase
{
public:
ElementOpResultFirst elementOperation()
{
// Implementation dependant operation code.
return ElementOpResultFirst();
}
//ElementOpResultSecond elementOperation()
//{
//// Implementation dependant operation code.
//return ElementOpResultSecond();
//}
};
class EfficientElement
:
public ElementBase
{
public:
ElementOpResultFirst elementOperation()
{
// Implementation dependant operation code.
return ElementOpResultFirst();
}
//ElementOpResultSecond elementOperation()
//{
//// Implementation dependant operation code.
//return ElementOpResultSecond();
//}
};
class Data
{
public:
virtual void insertElement(const ElementBase&) = 0;
virtual const ElementBase& getElement(int key) = 0;
};
class DataConcreteMap
:
public Data
{
// Map implementation
public:
void insertElement(const ElementBase&)
{
// Insert element into the Map implementation.
}
const ElementBase& getElement(int key)
{
// Get element from the Map implementation.
}
};
class DataConcreteVector
:
public Data
{
// Vector implementation
public:
void insertElement(const ElementBase&)
{
// Insert element into the vector implementation.
}
const ElementBase& getElement(int key)
{
// Get element from the Vector implementation
}
};
class Abase
{
public:
virtual void aFunction() = 0;
};
class Aconcrete
:
public Abase
{
public:
virtual void aFunction()
{
std::cout << "Aconcrete::function() " << std::endl;
}
};
class Bbase
{
public:
virtual void bFunction(Data& data) = 0;
};
class Bconcrete
:
public Bbase
{
public:
virtual void bFunction(Data& data)
{
data.getElement(0);
std::cout << "Bconcrete::function() " << std::endl;
}
};
// Add a static abstract factory for algorithm and data generation.
class ClientInterface
{
std::unique_ptr<Data> data_;
std::unique_ptr<Abase> algorithmA_;
std::unique_ptr<Bbase> algorithmB_;
public:
ClientInterface()
:
// A Factory Method is defined for Data, Abase and Bbase that
// produces the concrete type based on an entry in a text-file.
data_ (std::unique_ptr<Data> (new DataConcreteMap())),
algorithmA_(std::unique_ptr<Abase> (new Aconcrete())),
algorithmB_(std::unique_ptr<Bbase> (new Bconcrete()))
{}
void aFunction()
{
return algorithmA_->aFunction();
}
void bFunction()
{
return algorithmB_->bFunction(*data_);
}
};
// Single client code: both for testing and final version.
int main()
{
ClientInterface cli;
cli.aFunction();
cli.bFunction();
return 0;
};
What I tried to do is to have a single ClientInterface class, which is
able to choose different Strategies and Data implementations at
run-time. The algorithms and data implementations are chosen using the
Factory Method which reads the strings from an input file and selects
the algorithm and data implementation in the ClientInterface
constructor. The run-time choice of data and algorithms is not
provided in the code model below.
Sounds like you have the basis for some of it here: Either just produce a set of files to test with that produce the right different sets of inputs. Or refactor the Factory function so that the reading of the file and the strings are separate, so you can call your factory function [internals] with a a string from the code.
Can I assume that for the same number of Elements and the
ClientInterface configuration obtained at run-time, the overhead
induced by the use of polymorphism for the Element type will have the
same impact on all configurations of the Data and Algorithm
implementations? In this case, I can run the automated tests, decide
on the configuration of the Data implementation and the Element
implementation, and define a statically configured
EfficientClientInterface to be used in the productive code?
I don't think you can make that assumption. Different implementations may well have different effects on the algorithms - copying a 100 byte string is significantly harder than copying a 4 byte integer, for example. So what the data is, and how it's organized will have some effect on the work you do. Of course, since you haven't described in much detail what your Elements actually contain, it's all guesswork.
1) How can an Element support different operations when overloading is
not working for return types? If I make the operation a template, it
needs to be defined at compile-time, which messes with my automated
testing procedure.
Make a factory class that returns an ElementBase reference or pointer? That's my immediate reaction to this question, but again, the detail in your question is sufficiently vague that it's hard to say for sure.
In the real application, how does this work? Is it done by templates, then you'd better implement the testcode by templates, and fill it out with a selection of realistic variations on what you think the real system is likely to do.
2) How can I design this code better to achieve the goal?
Try to reuse the production code?
3) Is there a better overall approach to this problem?
Not sure yet.