How best to let a user redefine a class method? - c++

I have a library with a completely general implementation with the exception of a single class A. This class only has a single function int format(int i){} but can't be used as is: format depends on each different application and needs to be user-defined. In particular, format has quite a few if-then statements that need to be set correctly for the environment of the application. However the rest of the library is completely general, and will work with any choice of format that is within certain specifications.
The Question: What's the best way to let the user of my library define how format works? This needs to be done on the code level (as opposed to just using a configuration file).
The obvious idea would be to have the user directly rewrite the definition of format directly on the source code, but that doesn't sound like the most elegant way to do this.
Another idea would be to use inheritance: Have the user define a userA class inheriting from A and then hide the format function. But the rest of the library uses class A instead of userA. At this point, it could be possible to replace all instances of A with a typename desiredA and then have the user define that typename to be userA. This is not very elegant either.
There must be a better way to do this right?

Here's a method that I have used in the past.
Add the ability to let the user to register a function of their choosing.
If a user defined function has been registered, call it. Otherwise, use some default function.
using UserFunctionType = int(*)(int i);
UserFunctionType registeredFunction = nullptr;
void registerUserFunction(UserFunctionType f) { registeredFunction = f; }
int format(int i)
{
if ( registeredFunction )
{
return registeredFunction(i);
}
else
{
// Some default implementation
}
}
User code would be something like:
int myFunction(int i)
{
// Return whatever makes sense.
}
int my_init()
{
registerUserFunction(myFunction);
return 0;
}
// Make sure my_init() gets called at program startup time.
static int dummy = my_init();

Related

Two versions of the program depending on the input parameter without code duplication

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.

C++ load constructor from variable name

I have a school project in which there is a world simulation. Teacher wants me to do save/load system and I've encountered a problem. My data is saved in a format name x y so saving works fine.
Problem starts when I want to load data. This is my solution:
switch(name) {
case "Human":
new Human(x,y);
break;
case "Dog":
new Dog(x,y);
break;
}
Is there a way to generalize this? Saved name is always exactly the same as constructor name, so I would just like to do something like:
string name = "Human"
new <name>(x,y) <-> new Human(x,y);
My solution works just fine but following the rules of OOP, the world shouldn't know what kind of organisms live on it.
No, currently there isn't. C++ doesn't have reflection and introspection which is required for something like this to work. (There is active work being done in this direction, but don't expect it to come into standard very soon).
There are serialization libraries which will hide the equivalent of your intended switch and provide a simpler, safer API and they are the preferred way to do this in production, but for your assignment you should do it manually.
By the way, your code is syntactically incorrect, it shouldn't compile, but I guess I get what you meant.
You can simplify the process of string comparison using macros. But you still have to provide a list of classes that need to be searched.
#define CHECK_RETURN(name, className) if (name == #className) return new className();
std::string name = "Dog";
CHECK_RETURN(name, Human);
CHECK_RETURN(name, Dog);
CHECK_RETURN(name, Banana);
No. Not in C++. To do that you would need reflection, and that is not a thing C or C++ can do.
What is done in some cases is to write an Interface Definition Language, aka IDL, and from that generate code that implements the interface. These interfaces often include the ability to serialize and deserialize objects in order to send them across the network, but it works for files as well.
That's probably more than you want to get into.
What you want for a simple C++ project is to implement a Factory. I assume all these things are Organisms so you want an OrganismFactory like:
class OrganismFactory {
public:
static std::unique_ptr<Organism> Create(const std::string& line);
};
And then it reads the contents of a line and produces an Organism. Probably using something like your case statements. Or you can create a std::map or std::unordered_map of the class name and a function pointer to the rest of the line. Then there's no if or case for each object type, just a map lookup and an indirect function call. You still have to write the code to fill in the map though, and write each function.
And yes by OOP rules you need to create interfaces/virtual methods in the Organism base class for everything that Organisms do in the world.
You can create your own lookup table of creator functions to handle this, for example:
class Organism
{
public:
virtual ~Organism() {}
};
class Human : public Organism
{
...
};
class Dog : public Organism
{
...
};
...
using OrganismPtr = std::unique_ptr<Organism>;
using CreateFunc = OrganismPtr(*)(int, int);
std::map<std::string, CreateFunc> mymap;
mymap["Human"] = [](int x, int y) -> OrganismPtr { return new Human(x, y); }
mymap["Dog"] = [](int x, int y) -> OrganismPtr { return new Dog(x, y); }
...
string name = "Human";
OrganismPtr o = mymap[name](x, y);
// use o as needed...

macro that defines entire derived class from one function and certain type specifiers?

I have a class called system. A system takes some object managers and changes all objects in them in some way.
For example there might be a system that draws all images in a imageManager.
Every derived class works somewhat like this (pseudo code):
class someChildClass : public System{
private:
someObjectManager &mang1; //these are used by the update method.
someOtherObjectManager &mang2;//the update method changes these somehow
public:
someChildClass(someObjectManager &mang1, someObjectManager &mang2)
:mang1(mang1),mang2(mang2){
}
virtual void update(){
//this is pure virtual in the System base class.
//Do something with the managers here
}
}
I feel like writing everything but the update method is a waste of time and a source of errors. I wanted to write a macro that basically makes a class like this like so:
QUICKSYSTEM(thisIsTheSystemName, someObjectManager, mang1, someOtherObjectManager, mang2, ... (infinite possible Managers. So a variadic macro?)){
//this is the update function
}
}//this is the end braked for the class declaration. Its ugly but I dont know how I could do the function differently?
well I am having some problems making the macro. Everything works fine until I need to split the variadic arguments into the names and the types. I dont know if this is even possible now, since I cant go back and forth in the arguments easily or apply a easy step to them to make sure that every 2nd is the name of the variable. I would be ok with omitting the possibility for names and just had the types with some sort of automatic naming (manager1,manager2,manager3 or something like that).
If this isnt possible using a macro, what would be a better way to avoid mistakes and cut some time in the constructor and class declaration part?
Yeah, macros are really, really not the way to do this. C++ has templates, which follow C++ syntax and support C++ expressions. Macros instead use their own preprocessor language, which is almost entirely unaware of C++.
You'll want to read up a bit on std::tuple as well. It's going to be rather tricky to handle all those managers with those names. Tuples are the Standard solution for that. managers.get<0> and managers.get<someObjectManager> both work.
Variadic templates are the tool you need here:
#include <iostream>
#include <tuple>
#include <functional>
struct System { void virtual update() = 0; };
template<class... Managers>
struct ManagedSystem : System
{
std::function<void(Managers&...)> _update;
std::tuple<Managers&...> _managers;
template<class F>
ManagedSystem(F update, Managers&... managers) : _update(update), _managers(managers...) {}
void update() override { _update(std::get<Managers&>(_managers)...); }
};
int main()
{
int n = 0;
double d = 3.14;
auto reset = [](int& a, double& d) { a = 0; d = 0.0; };
ManagedSystem<int, double> ms{reset, n, d};
ms.update();
std::cout << "n = " << n << ", d = " << d << "\n";
// n = 0, d = 0
}
The idea is to define a templated-class (ManagedSystem) taking as template-parameters multiple manager types. This class inherits from Systemand provides a constructor taking:
an update functor,
and references to manager whose type is defined by the template parameters of the class.
The said managers are registered internally in an std::tuple and (with a bit of parameter pack magic fed to the update functor.
From there, you can define an inherited class from System by providing an update function and a type list. This avoids the use of ugly and type-unsafe macros in favor of the not-less ugly but type-string templates ;)

C++ using callbacks of an arbitrary class with arbitrary parameters

I want to implement a class with a function able to callback to methods from the object that called that function, without information about it.
Imagine we want to callback to some methods of the class Game from Library:
void Game::display(string a) {
cout << a << endl;
}
int Game::sum(int a, int b) {
return a + b;
}
void Game::start() {
lib = new Library();
lib->doSomething(/* somehow pass information about the functions*/);
}
And then:
void Library::doSomething(list_of_callbacks L /*or something like this*/) {
L[0]("hi"); //L[0] is Game::display
L[1](2,3); //L[1] is Game::sum
}
It needs to work not just with Game, but with any class. The methods we want to call back may need access to the object's attributes (so not necessarily static).
I'm kinda new to C++; I've been searching on the topic for hours now but in most cases the return type or the parameters of all the callback methods are the same. I've tried to get something working with templates and std::function / std::bind but unsuccessfully.
Thanks, and sorry if I didn't make myself clear enough, it's my first post around here.
EDIT:
The doSomething function is going to be generated (translated) by an external tool, which has information about the list of functions (like, the function in L[0] takes these parameters or these others, etc).
If what I'm asking can't be done in C++, isn't there any other way to achieve the same goal? Being able to get information from the caller?

OO Design -- where to put non-member functions

I have a class with a complex construction process with many parameters. Multiple clients share objects of this class, and the union of these clients parameters are used to instantiate the class. Therefore I have a factory class that stores these requirements, checks consistency of the various clients' requests, and instantiates the class.
Additionally, there are a common set of use models (or sets of parameters) which multiple clients use for multiple factories.
For instance, consider an example. (Note that the actual code is C++, but my experience is in Python so I'll pseudo-code in Python. Yes, I know that this example wouldn't actually work as-is.)
class Classroom:
def __init__(self, room_size=None, n_desks=None, n_boards=None,
n_books=None, has_globe=False, ... ):
...
class ClassroomFactory:
def __init__(self):
self._requirements = dict()
def addRequirement(self, name, value):
if name.startswith("n_"):
self._requirements[name] = max(value, self._requirements.get(name, 0))
...
def createClassroom(self):
return Classroom(**self._requirements)
# instantiate the factory
factory = ClassroomFactory()
# "client 1" is a geography teaacher
factory.addRequirement("n_desks", 10)
factory.addRequirement("n_boards", 1)
factory.addRequirement("has_globe", True)
# "client 2" is a math teacher
factory.addRequirement("n_desks", 10)
factory.addRequirement("n_boards", 1)
# "client 3" is a after-school day-care
factory.addRequirement("room_size", (20,20))
factory.addRequirement("has_carpet", True)
room = factory.createClassroom()
The common use model is as a teacher, we need 10 desks and a board. I think this is best served by a non-member function/decorator, something like:
def makeTeacherRoom(factory):
factory.addRequirement("n_desks", 10)
factory.addRequirement("n_boards", 1)
return factory
This seems like a great example of the "prefer non-member/non-friend to member" paradigm.
The thing that I'm struggling with is, within the framework of a much bigger OO code, where should these types of non-member functions/decorators live, both in terms of namespace and in terms of actual file?
Should they live in the factory's file/namespace? They are closely related to the factory, but they're limitations on the general factory, and need not be used to use the factory.
Should they live in the client's file/namespace? The client understands these use models, but this would limit re-use amongst multiple clients.
Should they live with a common base class of the clients (for instance, one could imagine a "teacher" class/namespace which would also provide the non-member function makeTeacherRoom(), which would be inherited by MathTeacher and GeographyTeacher.
Should they live somewhere else completely, in a "utils" file? And if so in which namespace?
This is primarily a personal decision. Most of your options have no technical negative effects. For example:
They could, because of locality of use, but it's not necessary.
They could, because of locality of data, but again...
They could, although this one does seem like it could make things a bit messier. Making utility classes, you may have to end up inheriting them, or making parts virtual to override later, which will get ugly pretty quick.
This is my personal favorite, or a variant of this.
I typically make a relevantly-named util file (or class with static methods) and put it in the same namespace as the classes it utilates (the more helpful version of mutilate). For a Education::Teacher class, you could have a Education::TeacherUtils file or class containing the functions that operate on Teacher. This keeps a pretty obvious naming tie-in, but also puts the util functions in their own area, so they can be included from whatever needs them (in the Teacher.cpp or similar would prevent that). In the case of a class, you can make the util and base classes friends, which is occasionally helpful (but something to use rarely, as it may be a smell).
I've seen a naming variation, Education::Utils::Teacher, but that's somewhat harder to translate to files (unless you put things into a utils dir) and can also cause name resolution oddness (in some contexts, the compiler may try to use Education::Utils::Teacher instead of Education::Teacher when you didn't mean to). Because of this, I prefer to keep utils as a suffix.
You may want to handle non-member functions in a singleton class for your application. A factory maybe executed from the program, or another object.
C++ supports global functions (non member functions), but, using a single object for the application, "does the trick".
Additionally, since the "Classroom" object may be instantiated with many optional parameters, you may want to assign it, after calling the constructor ( "init" in python ).
// filename: "classrooms.cpp"
class ClassroomClass
{
protected:
int _Room_Size;
int _N_Desks;
int _N_Boards;
int _N_Books;
bool _Has_Globe;
public:
// constructor without parameters,
// but, can be declared with them
ClassroomClass()
{
_Room_Size = 0;
_N_Desks = 0;
_N_Boards = 0;
_N_Books = 0;
_Has_Globe = false;
} // ClassroomClass()
public int get_Room_Size()
{
return _Room_Size;
}
public void set_Room_Size(int Value)
{
_Room_Size = Value;
}
// other "getters" & "setters" functions
// ...
} // class ClassroomClass
class ClassroomFactoryClass
{
public:
void addRequirement(char[] AKey, char[] AValue);
} // class ClassroomFactoryClass
class MyProgramClass
{
public:
ClassroomFactoryClass Factory;
public:
void makeTeacherRoom();
void doSomething();
} // class MyProgramClass
void MyProgramClass::addRequirement(char[] AKey, char[] AValue)
{
...
} // void MyProgramClass::addRequirement(...)
void MyProgramClass::makeTeacherRoom()
{
Factory.addRequirement("n_desks", "10")
Factory.addRequirement("n_boards", "1")
} // void MyProgramClass::makeTeacherRoom(...)
void MyProgramClass::doSomething()
{
...
} // void MyProgramClass::doSomething(...)
int main(char[][] args)
{
MyProgramClass MyProgram = new MyProgramClass();
MyProgram->doSomething();
delete MyProgram();
return 0;
} // main(...)
Cheers
Personally I would make them static members of the class.
class File
{
public:
static bool load( File & file, std::string const & fileName );
private:
std::vector< char > data;
};
int main( void )
{
std::string fileName = "foo.txt";
File myFile;
File::load( myFile, fileName );
}
With static methods they have access to the private data of the class while not belonging to a specific instance of the class. It also means the methods aren't separated from the data they act on, as would be the case if you put them in a utility header somewhere.