now, of course the above can be inlined in a single method, which will be essentially faster, but leaves us with a composite method, instead of a case where both processes (tone generator and oversampler) are separated in classes and can be reused by other processes in a more object oriented class structure.
lets take a look at a case where the main processing method is in the parent class and the other processing method (a processing container) is in a sub class (or a class which is initiated inside the parent class).
here is an example:
// include a class from a header
#include "childclass.h";
// define parent class
class parentclass
{
private:
// child class instance
childclass _childclass;
// some variable
float some_variable;
public:
// constructor
parentclass()
{
// init stuff
some_variable = 5.f;
}
// the main method
virtual void processing_main_method(const float input)
{
// call a method from the child class and pass the input variable
_childclass.some_method(input);
}
}
how about callbacks i.e. passing a method which to be called from another method? in the c programming language to achieve that function pointers are used.here is a nice article that covers mostly everything on the subject of function pointers on callbacks:
http://www.newty.de/fpt/callback.html
but what if we decide to make a callback from the child class to a method in the parent class? the logical way to achieve that is to declare a method in the parent class as static. http://www.eelab.usyd.edu.au/ee_database/programming/c++/cplusplus-5.html:
(note: info on static functions in the same article - section 5.2)
some code for our example:
// ==============
// program.cpp
// ==============
// include a class from a header
#include "childclass.h";
// define parent class
class parentclass
{
private:
// child class instance
childclass _childclass;
// some variable
float some_variable;
public:
// constructor
parentclass()
{
// init stuff
some_variable = 5.f;
}
// ************************
// the callback method
// ************************
static float processing_callback_method(const float input)
{
// do something
}
// the main method
virtual void processing_main_method(const float input)
{
// call a method from the child class and pass the input variable
// and also the local processing_callback_method
_childclass.some_method(processing_callback_method, input);
}
}
// ===============
// childclass.h
// ===============
// define child class
class childclass
{
private:
float some_variable;
public:
// constructor
childclass()
{
// init stuff
some_variable = 5.f;
}
// ********************************************
// the method that is called from parent
// notice how the function pointer is passed
// ********************************************
virtual float some_method(float (*callback_function)(float), const float input)
{
// do something with input
// ....
// then do a callback
return(*callback_function)(input);
}
}
here is a quick diagram of the above:
.------------------------------------------.
|[*mainclass] |
| |
| processing_main_method |
| | |
| | processing_callback_method |
| V ^ |
| | | |
| .--------|------------------|---. |
| | | | | |
| | '--> some_method ->' | |
| |[*subclass] | |
| '-------------------------------' |
'------------------------------------------'
so far so good...
but now we face the issue that static methods cannot access non-static members. actually there is much sense in that if we think about it:
The static functions can therefore address only the static data of a class; non-static data are unavailable to these functions. If non-static data could be addressed, to which object would they belong? Similarly, static functions cannot call non-static functions of the class. All this is caused by the fact that static functions have no this pointer.
the way to solve this would be to pass an instance to the parent class to the subclass function (some_method) and then pass this instance back to the static callback function (processing_callback_method). an example (with void pointers):
// ==============
// program.cpp
// ==============
// include a class from a header
#include "childclass.h";
// define parent class
class parentclass
{
private:
// child class instance
childclass _childclass;
// some variable
float some_variable;
public:
// constructor
parentclass()
{
// init stuff
some_variable = 5.f;
}
// *******************************
// a non-static member function
// *******************************
virtual float non_static_method(const float input)
{
return input * 2.f;
}
// ************************
// the callback method
// ************************
static float processing_callback_method(void* _this, const float input)
{
// cast the class
childclass* _pthis = (childclass*) _this;
// do something with a non-static member
_pthis->some_variable = 1.f;
// call a non-static member function
return _pthis->non_static_method(input * 0.5f);
}
// the main method
virtual void processing_main_method(const float input)
{
// call a method from the child class and pass the input variable
// and also the local processing_callback_method
_childclass.some_method(processing_callback_method, input);
}
}
// ===============
// childclass.h
// ===============
// define child class
class childclass
{
private:
float some_variable;
public:
// constructor
childclass()
{
// init stuff
some_variable = 5.f;
}
// ********************************************
// the method that is called from parent
// notice how the function pointer is passed
// but also an instance of the parent class
// ********************************************
virtual float some_method(void* _parent, float (*callback_function)(void*, float), const float input)
{
// do something with input
// ....
// then do a callback
return (*callback_function)(_parent, input);
}
}
so that is all.
please note that i have not tested any of the code from above and its just provided as a guideline.
lubomir
0 comments:
Post a Comment