Hello!
I have a (probably) dumb question. Is it possible to have a class and have a method that needs to be written for each member?
I'll explain myself: I'm making a program with SFML that needs to be divided in more phases (such as login, main page and so on) and I figured it could be a good idea to define a class to gather some common data between pages, like some booleans to see if the page has been initialized, message holders, page requests and similar.
For a matter of mental order I'd like to make it so that each page has an "execute" function that does all the stuff the page needs to do, but of course this function should be different for each member of the class. Is it possible (and does it make sense) to write something like that?
NOTE: I could have the class AND external individual functions, but I just wanted to ask this question that might be useful in a future project.
1) A base class that every page will inherit from, holding all the common data, that each page would then inherit from and provide its own execute function. Something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
class page
{
bool beenInitialised = false;
vector<messages> messageHolder;
// etc
virtualvoid execute() = 0; // pure virtual, must be provided by inheriting class
};
class loginPage : public page
{
void execute() override
{ // do something }
};
Every inheriting class provides its own execute function, with whatever parameters etc you like.
2) A page class that you must provide the execute function to upon construction:
1 2 3 4 5 6 7 8 9 10 11 12
class page
{
bool beenInitialised = false;
vector<messages> messageHolder;
// etc
std::function<void(int)> functionToExecute;
// constructor - you provide function to execute
page (std::function<void(int)> inputParameter) :
functionToExecute(inputParameter){};
}
I expect this could be templatised so you can provide a function of whatever form you like.
Yes, I really like the second option! I've never used std::function though, i got the idea but I still don't understand why you represented std::function<void(int)> inputParameter this way.
Why is it a function as well?
In the second option, you need to set the function to be executed. You need to give it the std::function object that will be executed.
It is dangerous to have an object in existence in a mal-formed state. You could simply have something like this (probably wrong syntax, but should give you the idea):
page somePageObject; // create the object - no function to execute has been set
somePageObject.functionToExecute = some_std_function_object; // now set the function to execute
somePageObject.execute(); // some time later, tell it to execute the function
but between the first and second line, the page object exists in a bad state. What happens if you do this:
1 2
page somePageObject;// create the object - no function to execute has been set
somePageObject.execute(); // tell it to execute the function - oh no! It was never set!
It's dangerous.
But if you use a constructor ( http://www.learncpp.com/cpp-tutorial/85-constructors/ ) that accepts the function to execute as a parameter, then there is no way to create the page object in a bad state. It's much safer.
One of C++'s big improvements over C is the idea that you create classes in good states, through constructors. In C, this sort of thing used to be common:
1 2
struct someStruct; // dangerous to use
initialise(someStruct); // now it's been initialised - now it's safe
and it was also common to get it wrong.
Well written constructors make C++ safer, because well-written constructors make it impossible for you to have an object in a bad state right after creating it.