I have an abstract class Engine3D and it's structures (Vector3D, etc.) in the header files.
Now, I have an implementation for that class, ConcreteEngine3D : Engine3D. Also, I have other classes like ConcreteVector3D : Vector3D that have additional members and methods that will be used inside ConcreteEngine3D (for the sake of this example, let's say it's float length and calculateLength()).
In main.cpp I have the code:
#include "ConcreteEngine3D.h"
Engine3D * engine;
...
int main(){
engine = new ConcreteEngine3D();
Vector3D* vector = new Vector3D(engine, 10, 5, 2);
}
I want the variable vector be of type ConcreteVector3D*.
I will need that type in ConcreteEngine3D, but in main.cpp I shouldn't even know it's that type and don't have to use extended fields like length. Also, I can't use in main.cpp anything specifically from ConcreteEngine3D.h (only Engine3D.h) - it's for the flexibly, changing the implementation must means only changing the inclusion and line with new ConcreteEngine3D().
I do not want to modify that code above or original headers from Engine3D.
In the constructor of Vector3D I always put a pointer to Engine3D object (and I give here ConcreteEngine3D type).
Maybe can I do something in the constructor of Vector3D to change the type of it?
For example call Vector3D* Engine3D::convert(Vector3D v) inside of the constructor which will be inherited from Engine3D in ConcreteEngine3D (which creates a new ConcreteVector3D object with fields from Vector3D and returns it).
Of course that code doesn't work:
Vector3D::Vector3D(Engine3D *engine){
//how to 'return' or 'convert' the type to the one that returns engine->convert(this);
}
So basically, I want to get the effect of code below but without the line vector = engine->convert(vector) or Vector3D* vector2 = new ConcreteVector3D(engine, 10, 5, 2).
#include "ConcreteEngine3D.h"
Engine3D * engine;
...
int main(){
engine = new ConcreteEngine3D();
Vector3D* vector = new Vector3D(engine, 10, 5, 2); //produces Vector3D, not ConcreteVector3D
vector = engine->convert(vector); //cannot be here! but creates the right object
Vector3D* vector2 = new ConcreteVector3D(engine, 10, 5, 2); //also creates rights object, but cannot be here!
}
Also, I don't want to use factory in Engine3D or ConcreteEngine3D. I want to allow the 'user' create Vector3D just the way I have written in the first code.
It sounds like you would want to use abstract factory pattern to instantiate your objects so that you would not have to directly call constructors of the concrete classes. Then, in case you would want to change the concrete types that implement your interfaces, you would only need to either link in a different implementation of your abstracy factory, or select a proper factory implementation at run time.
Edit: Missed the "don't want to use factory"... Anyway you will need some kind of redirection, because constructor will return the type you instantiate. Closest you can get is probably creating a static factory method "create" to class Vector3D that returns a pointer to Vector3D, but internally creates an instance of concrete implementation class. In case you do that, it is good practice to make the constructor of Vector3D private to prevent creating the vector in "wrong way".
Andrew Tomazos, about the not clear writting - Sorry for that :/
I must agree with Captain Giraffe, that I cannot achieve it without any changes in main.cpp. I used the a little modified factory pattern:
I had to made Vector3D::create() static function which will call Engine3D::convert() and returns it's result. So the code will be:
#include "ConcreteEngine3D.h"
Engine3D * engine;
...
int main(){
engine = new ConcreteEngine3D();
Vector3D vector = Vector3D::create(engine, 10, 5, 2);
}
Inside of Vector3D::create:
return engine->convert(new Vector3D(x,y,z));
Which will produce ConcreteVector3D (because engine is of type ConcreteEngine3D).
Minimal changes in main.cpp, acceptable (no ConcreteVector3D mentioned in the main.cpp).
Once more, thanks for help, to all of you! :-)
Related
I am solving the following problem. I am working on an optimization program in C ++ which, depending on the initial settings of the user, uses various regulations (standards) to calculate the target function. Suppose we have a method A based on some norm and a method B based on another norm to calculate the target function. The user is setting the right standard before starting the program. The rest of the code is the same. During optimization, the target function is iteratively called over and over again. Of course, there is a simple solution: each time the target function is called, the IF condition is used to decide which standard to use. But because the program has to make decisions in every iteration, it seems to be ineffective. The second option is to create 2 independent codes and run only the one with the required standard. This, in turn, is ugly in terms of duplicate code.
I imagined that I would create 2 different classes and use the selected class using the IF condition when constructing the object. This would make the program decide only once when creating the object, but during the iteration itself the object would be clearly defined. Unfortunately, this does not work because objects cannot be created in IF conditions.
//-----------------------------------------------------------
// Create object sensor based on input
if(data.sensors_tipe == "Uniaxial_025") Sensor_Uniaxial_025 sensor(data);
else if (data.sensors_tipe == "T_rosette_05") Sensor_T_rosette_05 sensor(data);
else report.error("some error");
// rotation test
int element_index = 1;
double orientation_angle = 3.490658503988659;
sensor.rotate(element_index, orientation_angle);
Another way I would like is to set the correct method using a parameter in the constructor. Unfortunately, that probably isn't possible either.
I am a beginner and I did not find the answer anywhere. So maybe someone can help. Thanks
This is a good job for templates, which are "recipes" to generate code.
The end result will be duplicated machine code, but without the duplication in the source.
template<typename MethodT>
float optimize(const MethodT& method) {
float v = method();
// etc...
}
float methodA();
float methodB();
int main() {
auto a = optimize(methodA);
auto b = optimize(methodB);
}
First, the solution with if may be not that bad. It is branch on each function call, but the branch should be predicted well.
Second, if the functions that implement method A and method B are large enough to miss inlining, use function pointer.
Otherwise, use static polymorphism with templates, method A and method B may be passed via template parameter as functors.
In case, the user can change standard after programm compilation (for example, before each run) you can create interface and 2 child from it.
So, at startup you should create the instance (one of 2) you need through new. And then you can use it.
You can't use that algorithm with stack instances.
One way is to use inheritance.
class Sensor
{
public:
virtual void rotate(int, double) = 0;
};
class Sensor_Uniaxial_025 : public Sensor
{
public:
virtual void rotate(int, double) {/*stuff*/};
};
class Sensor_T_rosette_05 : public Sensor
{
public:
virtual void rotate(int, double) {/*stuff*/};
};
Sensor* sensorToUse;
//-----------------------------------------------------------
// Create object sensor based on input
if(data.sensors_tipe == "Uniaxial_025") sensorToUse = new Sensor_Uniaxial_025(data);
else if (data.sensors_tipe == "T_rosette_05") sensorToUse = new
Sensor_T_rosette_05(data);
else report.error("some error");
// rotation test
int element_index = 1;
double orientation_angle = 3.490658503988659;
sensorToUse->rotate(element_index, orientation_angle);
The example above, with new, comes with serious memory management issues. But if you pre-allocate the sensor for each type, in a single instance, and use a look-up instead it works well.
The alternative is with template. See other answers for these approaches.
I'm new to c++ and I'm trying to make a generic switch (i.e. the device, not the C++ statement) that could be used to blink lights, turn beeps on and off, etc, in my Arduino project.
I could create a switchable interface and implement that in the classes that I want to "switch". But since I'm doing it as study purposes and I saw the pointer-to-functions ability in C++ (that is new to me since I come from C# and Java), I tough it would be a good opportunity to give it a try...
The problem is that I can pass the function in my code only if it's a local function but it won't work if I try to pass a function from another object like a led for example.
Some code to illustrate the problem. This is the switch.cpp, it recieves the On and Off functions in it's constructor and it has a update method that is called inside the loop method in the Arduino ino main class:
auto_switch.cpp
using switch_function = void(*)();
auto_switch::auto_switch(const switch_function on_function, const switch_function off_function, const int max_speed_count)
{
//sets all variables...
}
void auto_switch::update(const unsigned long millis)
{
//turn switch on and off...
}
And this is my ino file
ino file
#include <Arduino.h>
#include "led.h"
#include "auto_switch.h"
led* main_led;
auto_switch* led_switch;
int slow_speed;
//ugly code
void turn_led_on()
{
main_led->turn_on();
}
//ugly code
void turn_led_off()
{
main_led->turn_off();
}
void setup() {
main_led = new led(2, 3, 4, true, color::white);
//ugly code
led_switch = new auto_switch(turn_led_on, turn_led_off, 3);
slow_speed = led_switch->add_speed(100, 100, 3, 1000);
led_switch->set_active_speed(slow_speed);
led_switch->turn_on();
}
void loop() {
led_switch->update(millis());
}
It works but I had to make a local function (turn_led_on and turn_led_off) to be able to assign the inner functions as a parameter to the auto_switch constructor, the parts that I've wrote //ugly code
I wanted to do something like this, without the glue code in between:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
Is it possible? I've read something about static pointer to function and some std functions that help with that, if I get it right the glue code is necessary in this case so that the compiler can know where the functions are coming from I guess (from which object), but since the functions I need to call cannot be static I've discarded this option, and the std functions I believe it can't be used with the Arduino or could but shouldn't for performance limitations...
Anyway, does it make sense, can it be done using pointer to functions or should I create a interface or something different?
Before deciding how to do it, the qquestion is what do you want to do and why. Because, maybe there are better alternatives using simple C++ idioms.
Option 1: specialization with polymorphism
Do you want to specialize some functions of your switch, so instead of calling the function of the auto_switch you'd call dome more specialized ones ?
In this case you wouldn't do:
//doesn't work
led_switch = new auto_switch(main_led->turn_on, main_led->turn_off, 3);
but instead you would rely on polymorphism with virtual functions in the base class:
class auto_switch {
...
virtual void turn_on();
virtual void turn_off();
...
};
and write a specialized class for the leds:
class led_witch : public auto_switch {
...
void turn_on() override;
void turn_off() override;
...
};
In fact, the compiler will generate some function pointers behind the scene, but you don't have to care:
auto_switch s1=new auto_switch(...);
auto_switch s2=new led_switch(...); // no problem !!
s1->turn_on(); // calls auto_switch::turn_on()
s2->turn_on(); // calls led_switch::turn_on() since the real type of s2 is led_switch
But event if each object's behavior is dynamic on the the base of the real class of the object, the objects of the same class share a behavior that was predefined at compile time. If this is not ok, go to the next option.
Option 2: the member function pointer
The functions of another objects can only be invoked with that object at hand. So having a function pointer to a led function is not sufficient: you also need to know on which led it shall be applied.
This is why member function pointers are different and somewhat constraint: you can only invoke functions of class of your member function pointer. If polymorphism is sufficient (i.e. if derived class has a different implementation of a function already foreseen in the base classe) then you are lucky. If you want to use a function that only exists in the derived class and not in the base class, it won't compile.
Here a simplified version of auto_swith: I provide a function, but allso a pointer to the object on which the function has to be invoked:
class auto_switch{
void (led::*action)();
led *ld;
public:
auto_switch(void(led::*a)(), led*l) : action(a), ld(l) {}
void go () { (ld->*action)(); }
};
// usage:
auto_switch s(&led::turn_off, &l1);
s.go();
Online demo
Option 3 : the functional way (may that's what you're looking for ?)
Another variant would be to use the standard functional library to bind a member function and the object on which it shall be executed (as well as any need parameters):
class auto_switch{
std::function<void()> action;
public:
auto_switch(function<void()>a) : action(a) {}
void go () { action(); }
};
Here you can bind anything: any function of any class:
auto_switch s(bind(&led::turn_off, l1));
s.go();
auto_switch s2(bind(&blinking_led::blink, l2));
s2.go();
Online demo
Option 4 : command pattern
Now if you want to perform something on an object when you turn on and off the switch, but you need total flexibility, you can just implement the command pattern : this lets you execute anything on any object. And you don't even need a function pointer.
Let us assume the following class:
class FileManipulator
{
static InputTypeOne * const fileone;
InputTypeTwo *filetwo;
public:
FileManipulator( InputTypeTwo *filetwo )
{
this->filetwo = filetwo;
}
int getResult();
};
FileManipulator uses data from both files to obtain output from getResult(). This means multiple iterations over filetwo and multiple constructions of FileManipulators via iterations for different InputTypeTwo objects. Inputs are, let us say, some .csv databases. InputTypeOne remains the same for the whole task.
The program itself is multi-modular and the operation above is only its small unit.
My question is how can I handle that static field in accordance with the object-oriented paradigm and encapsulation. The field must be initialized somehow since it is not a fixed value over different program executions. As far as I understand C++ rules I cannot create a method for setting the field, but making it public and initializing it outside of any class (FileManipulator or a befriended class) seems to me at odds with the encapsulation.
What can I do then? The only thing that comes to my mind is to do it in a C manner, namely initialize it in an isolated enough compilation unit. Is it really all I can do? How would that be solved in a professional manner?
edit
I corrected pointer to constant to constant pointer, which was my initial intention.
You can write a public static method of FileManipulator that would initialize the field for you:
static void init()
{
fileone = something();
}
And then call it from main() or some place where your program is being initialized.
One way of doing this which comes to mind is:
In the .cpp file
FileManipulator::fileone = NULL;
Then modify constructor to do the following:
FileManipulator( InputTypeTwo *filetwo, InputTypeOne *initValue = NULL)
{
if(fileone == NULL)
{
fileone = initValue;
}
this->filetwo = filetwo;
}
Or you could also define an init function and make sure to call it before using the class and after the CTOR. the init function will include the logic of how to init fileone.
first of all, excuse my poor english.
Well, i'm tryng to make a simple game in C++ with Allegro's library, but i don't know how to create an object array wich can be accesed from all clases.
To be more exactly, i have this code in the main() function of the principal class:
CBody **objs = new CBody*[n];
objs[0] = new CBall(320,240);
objs[1] = new CRing(500,120);
Then i need to make a function in CBall's class to check collision with CRing instance. Something like:
bool CBall::CheckRingCol(){
return (colCircle(myX,myY,myRadious,objs[1]->myX,objs[1]->myY,objs[1]->myRadious));
}
Any ideas?
Thanks you, guys!
First, do not use double pointer madness. You don't need it.
You have an array of CBody, which presumably is a Base class (helps to post more code)
#include <memory>
typedef shared_ptr<CBody> spBody;
vector<spBody> bodies;
bodies.emplace_back( spBody(new CBall(320, 140)) ); // don't need to bother about delete when you use a shared_ptr
bodies.emplace_back( spBody(new CRing(500, 120)) );
Who calls the ball-ring collision?
You could pass the ring as an argument to bool CBall::CheckRingCol(const CRing*) const.
So I've a collection of C++ classes which I now have converting fine with Alchemy to a swc file and can call the exposed functions fine from my AS3 code.
What I'd really like to do is recreate stuff like Box2D's b2Vec.as class,
public class b2Vec2 extends b2Base {
public function b2Vec2(p:int) {
_ptr = p;
}
public function get v2():V2 {
return new V2(x, y);
}
public function set v2(v:V2):void {
x = v.x;
y = v.y;
}
public function get x():Number { return mem._mrf(_ptr + 0); }
public function set x(v:Number):void { mem._mwf(_ptr + 0, v); }
public function get y():Number { return mem._mrf(_ptr + 4); }
public function set y(v:Number):void { mem._mwf(_ptr + 4, v); }
}
This is a simple example, but shows what I'd like to do. On the C side of things, b2Vec2 is a struct,
/// A 2D column vector.
struct b2Vec2
{
/// Default constructor does nothing (for performance).
b2Vec2() {}
....
float32 x, y;
};
So, for this struct, it's easy to calculate that the first variable of a b2Vec2 object is a float, which will be the value in x and can be read via Alchemy's MemUser classes _mrf (read a fload from a point in memory) with _mrf(pointerAddress) and you can read in the second float with _mrf(pointerAddress + 4).
My question is, if you're not a C++ expert (me), is there any way to get the definition of a class, as in the addresses of all the variables within and what they are? So, for the b2Vec2 one, I'd imaging it'd be something like,
float32 x 0
float34 y 4
...
The reason I'm asking is because one of the classes in particular has loads of variables and to try and get each and every one's information so I can access it directly from the AS3 code would be lots of work and I'm going to assume I'll introduce plenty of human error to it.
The very general C++ answer is no. During run-time you can not discover what are the member variables of a particular struct.
How can I add reflection to a C++ application?
I don't know what the Alchemy compiled code looks like though. You can build some tool/preprocessor to generate the C++ classes or structs from some other representation and then that tool can also generate your AS3 accessors - that would be a way of eliminating the user error and some of the work. It might be tricky because figuring out the address of a member variable is not always that simple.
If you can call member functions in the C++ class why don't you move your get/set functions there and call those?
I actually got a good enough answer from the WCK guy, Jesse Sternberg. He got most of his AS3 classes that are paired with their C++ counterparts are done automatically during the build process in his own 'probe' folder. In there, there's one Box2D.c class that defines a load of templates at the top, then in the main function, probes classes for member variables and that prints out the relevant AS3 code for accessing them from that side.
It's a little bit funky to get used to, but certainly very handy and much better than doing it manually!