Stack of class member functions but the class isn't known yet - c++

I have something a little tricky to explain so I'll try my best. I have an InstructionScreen class that displays arrows & blocks of text that explain what each buttons does & etc. So in InstructionScreen I have a stack of member functions each of those functions will create some arrows & text to explain what a different button does.
The InstructionScreen will be subclassed into MenuInstructScreen, OptionsInstructScreen & etc. and in these classes I will create custom functions that will create arrows & text to explain their screens buttons.
The problem is declaring this stack in InstructionScreen because it will contain functions that are part of their subclass. I am thinking I can do this, but I use templates right?
So the problem in a nutshell is how do I declare a stack that will contain member functions of a class that doesn't exist yet?
The problem is a lot easier to understand & see if you look at this simple example:
typedef class InstructionScreen;
typedef class MenuInstructScreen;
template <typename FooClass>
typedef void (FooClass::*MemberFuncPtr)(); // will be typedef void (MenuInstructScreen::*MemberFuncPtr)();
class InstructionScreen
{
public:
InstructionScreen() {}
void runInstructions()
{
while ( !instructionStep.empty() )
{
(this->*instructionStep.top())();
instructionStep.pop();
}
}
protected:
stack <MemberFuncPtr> instructionStep;
};
class MenuInstructScreen : public InstructionScreen
{
public:
MenuInstructScreen()
{
// Set instruction schedule
instructionStep.push( &MenuInstructScreen::step2() );
instructionStep.push( &MenuInstructScreen::step1() );
}
void step1()
{
// create some widgets that point to buttons & widgets that contain text instructions
}
void step2()
{
// create some widgets that point to buttons & widgets that contain text instructions
}
private:
};
class OptionsInstructScreen : public InstructionScreen
{
public:
OptionsInstructScreen()
{
// Set instruction schedule
instructionStep.push( &OptionsInstructScreen::step2() );
instructionStep.push( &OptionsInstructScreen::step1() );
}
void step1()
{
// create some widgets that point to buttons & widgets that contain text instructions
}
void step2()
{
// create some widgets that point to buttons & widgets that contain text instructions
}
private:
};

C++ doesn't allow templated typedefs, but C++11 supports this via Template Aliases. If you don't have C++11 support in your compiler, you could achieve the same by using a functor such as Boost.Function.
typedef boost::function<void()> Func;
Since your typedef is for member functions that take no arguments, you could use the aboce to define a functor that returns void and accepts no arguments. Although it wouldn't be restricted to members of a specific class. You would push items onto your stack in derived classes using something like:
stack.push(boost::bind(&MenuInstructScreen::step2, this));
stack.push(boost::bind(&MenuInstructScreen::step1, this));
Your original example would now look something like this...
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <stack>
class InstructionScreen
{
public:
void runInstructions()
{
while (!instructionStep.empty())
{
boost::function<void()> func = instructionStep.top();
instructionStep.pop();
func();
}
}
protected:
std::stack<boost::function<void()> > instructionStep;
};
class MenuInstructScreen : public InstructionScreen
{
public:
MenuInstructScreen()
{
instructionStep.push(boost::bind(&MenuInstructScreen::step2, this));
instructionStep.push(boost::bind(&MenuInstructScreen::step1, this));
}
void step1()
{
//
}
void step2()
{
//
}
};
class OptionsInstructScreen : public InstructionScreen
{
public:
OptionsInstructScreen()
{
instructionStep.push(boost::bind(&OptionsInstructScreen::step2, this));
instructionStep.push(boost::bind(&OptionsInstructScreen::step1, this));
}
void step1()
{
//
}
void step2()
{
//
}
private:
};
int main() { }

There are no "template typedef"s in C++. In C++0x you can use template aliases, but support for that is limited at the moment.
Why not simply add a virtual function to your base class:
virtual void steps() { };
Then let each derived class implement it:
void steps() { step1(); step2(); }
Then you can store pointers-to-base-class in your stack and just call ->steps().

Related

How to track members and call their same-name method at one place at compile time?

I've got some widgets of different types. The widgets all have a method Update().
A top widget with member widgets needs to call all its members' Update() method in its UpdateMembers() method.
struct WidgetA{
void Update();
};
struct WidgetB{
void Update();
};
struct TopWidget{
WidgetA w1;
WidgetB w2;
//other widgets
void UpdateMembers(){
w1.Update();
w2.Update();
//other widgets
}
};
Manually updating UpdateMembers() when TopWidget's member list changes is error prone, so I need to do that automatically. The following code does the job, but it uses global states and has overhead in space and time. How can I do its job with some compile time programming?
#include <vector>
struct Updatable;
static std::vector<Updatable*> g_vec;
struct Updatable{
Updatable(){g_vec.push_back(this);}
virtual void Update()=0;
virtual ~Updatable();
};
struct WidgetA:Updatable{
void Update()override;
};
struct WidgetB:Updatable{
void Update()override;
};
struct TopWidget{
WidgetA wa;
WidgetB wb;
//other widgets
void UpdateMembers(){
for(auto w:g_vec){
w->Update();
}
}
~TopWidget(){
g_vec.clear();
}
};
As you ask for compile time solution without dynamic registering stuff, you may want something like the following:
struct WidgetA{
void Update(){ std::cout << "Update A" << std::endl;}
};
struct WidgetB{
void Update(){ std::cout << "Update B" << std::endl;}
};
template < typename ... CHILD_WIDGETS >
struct TopWidget{
//other widgets
std::tuple< CHILD_WIDGETS...> childs{};
void UpdateMembers(){
std::apply([](auto&&... element) { ((element.Update()),...); }, childs );
}
};
int main()
{
TopWidget< WidgetA, WidgetB > tw;
tw.UpdateMembers();
}
In this example all member widget types are known at compile time which makes it possible to store all this types as a tuple. And execute a function for every tuple element is quite easy as we have std::apply which does the job.
BTW: There is no need to make the whole class a template, maybe it is enough to have the tuple elements created directly if you do not need to have the same class with different member widget types in the same time.
see it running
Don't use global state. Let the Updateable register themself at their parent:
#include <vector>
struct Updatable;
struct Updater{
std::vector<Updatable*> g_vec;
void register_for_updates(Updatable* u){
g_vec.push_back(u);
}
void update();
};
struct Updatable{
Updatable(Updater* u) { u->register_for_updates(this);}
virtual void Update()=0;
virtual ~Updatable();
};
void Updater::update() {
for (const auto u : g_vec) {
u->Update();
}
}
struct WidgetA:Updatable{
WidgetA(Updater* u) : Updatable(u) {}
void Update()override;
};
struct WidgetB:Updatable{
WidgetB(Updater* u) : Updatable(u) {}
void Update()override;
};
struct TopWidget : Updater {
WidgetA wa;
WidgetB wb;
TopWidget() : wa(this),wb(this) {}
void UpdateMembers(){
Updater::update();
}
};
... but it uses global states and has overhead in space and time
Not sure what you call "overhead". If it is the vector, then thats not really overhead, but just what you need to get the job done. As long as C++ has no reflection you need to keep track of members to be updated yourself.

How to create a wrapper or intermediate layer to access a class, without exposing it?

I use a third party engine, that has a class "Sprite". My classes use sprite, and call its methods.
There is a probability that "Sprite" will be replaced in the future by some other game engine. I would like to have a layer between my class, and Sprite, so that it is easy to swap out Sprite in future.
I figure there are at least two ways to do this:
Implement a wrapper class that has a bridge method for every method in sprite, and that my code uses to access the sprite.
For Example:
Wrapper{
private:
Sprite* foo;
public:
void method1(){
foo->method1();
}
int method2(){
return foo->method2();
}
}
The downside with this approach is that there is a lot of work to write a method for each method in Sprite, even though all it is doing is just calling the method and returning whatever result. It is also a lot of maintenance work each time there is a change in sprite.
Alternative 2 : Some kind of magic by overloading the -> operator.
struct LoggingFoo : public Sprite {
void log() const { } //Just a method for logging.Doesn't matter.
Foo const *operator -> () const { log(); return this; }
Foo *operator -> () { log(); return this; }
};
Not very sure of all the things to keep in mind with this option ? For example, what happens to class methods ? Does it make sense to publicly inherit Sprite for this use case ?
Note: In practice, there is no object that is intended to inherit from Sprite in my code.
EDIT:
What would be the most concise way to create the wrapper, yet expose all public member variables and functions? For example, not having to specify each and every variable and function to expose ?
You just need to create a Wrapper class that publicly inherits from Sprite and use it. It automatically fully inherits all the methods and variables of the Sprite class in the Wrapper class with the same level of visibility:
class Sprite
{
public:
void foo(){};
void bar(){};
int mode = 0;
};
class Wrapper : public Sprite
{
};
int main()
{
Wrapper w;
w.foo();
w.mode = 5;
w.bar();
}
If in the future you switch to another library, you will inherit Wrapper from the new class and implement only removed or changed methods:
class NewSprite
{
public:
void foo(){}; // same interface
void new_bar(int mode){};
};
class Wrapper : public NewSprite
{
public:
void bar() // wrap new method
{
new_bar(mode);
}
int mode = 0;
};
But a better approach would be to build a higher-level Wrapper interface so that when you completely change the library API, you don't have to rewrite every method:
class Wrapper
{
public:
void do_operation() // high-level interface
{
s_.foo();
s_.mode = 5;
s_.bar();
}
protected:
Sprite s_;
};
class Wrapper
{
public:
void do_operation() // high-level interface
{
s_.foo();
mode = 5;
s_.new_bar(mode);
}
int mode = 0;
protected:
NewSprite s_;
};
int main()
{
Wrapper w;
w.do_operation();
}
You could also consider a slightly different implementation to your wrapper using private (i.e., is implemented in terms of) inheritance.
This implementation removes the burden of wrapping every function and instead just add a using statement for every function you want to expose.
#include <iostream>
class Sprite
{
public:
Sprite() : d_value(0) {}
void method1() { std::cout << "Sprite::method1()\n"; }
void method2() { std::cout << "Sprite::method2()\n"; }
int d_value;
};
class Wrapper : private Sprite
{
public:
using Sprite::method1;
using Sprite::method2;
using Sprite::d_value;
};
int main()
{
Wrapper w;
w.method1();
w.method2();
w.d_value = 3;
return 0;
}
Live Example

How to combine multiple variadic templated tuple classes into one class?

I have changed my approach from my original question to templatize the entire class instead and place it inside a variadic tuple. I can now use getters and setters the way that I would like them to be created. However, now I am trying to take it a step forward and combine the individual controllers into one controller.
#ifndef CONTROLLER_HPP
#define CONTROLLER_HPP
#include <functional>
#include <vector>
#include <iostream>
#include <utility>
template<typename...Classes>
class Controller
{
public:
Controller(Classes&...objects) : objects(objects...){}
void setValues(int value)
{
std::apply([&](auto&...x) { (x.updateValue(value),...);}, objects);
}
void getValues(std::vector<int> &values)
{
std::apply([&](auto&...x) { (values.push_back(x.get()),...);}, objects);
}
private:
std::tuple<Classes&...> objects;
};
#endif
With this I can do the following:
classA A;
classB B;
classC C;
classD D;
classE E;
classF F;
classG G;
Controller controller1(A,B,C);
Controller controller2(D,E);
Controller controller3(F,G);
controller1.setValues(20);
controller2.setValues(13);
controlelr3.setValues(32);
However, I want to take it a step further and combine the two like so:
Controller master(controller1,controller2,controller3);
master.setValues(40);
I have looked at this post talking about joining variadic templates, however I think this returns a type(?) and not a class. I also tried creating two overloaded classes, however I don't think I am creating the overload correctly:
template<typename...Classes>
class Controller
{
public:
Controller(Classes&...objects) : objects(objects...){}
void setValues(int value)
{
std::apply([&](auto&...x) { (x.updateValue(value),...);}, objects);
}
void getValues(std::vector<int> &values)
{
std::apply([&](auto&...x) { (values.push_back(x.get()),...);}, objects);
}
private:
std::tuple<Classes&...> objects;
};
template<Controller<typename ... > class Controllers, typename ...Classes>
class Controller<Controllers<Classes&...classes>...>
{
// create a new controller that takes all the combined classes
};
How can I combine any number of templated variadic templated classes into one class? I do have the ability to use C++17.
template<typename...Classes>
class Controller
{
Controller( std::tuple<Classes&...> tup ):objects(tup) {}
public:
template<class...Rhs>
Controller<Classes..., Rhs...> operator+( Controller<Rhs...> rhs ) const {
return std::tuple_cat( objects, rhs.objects );
}
...
giving us:
Controller master = controller1+controller2+controller3;
master.setValues(40);

Can i pass a function from a class to a constructor of another class and store it there to call later? C++

So basically I'm making buttons in a game, and the buttons are a called Button.
The class i want the function from to store is called SoccerLevelsClass. I've tried looking into function pointers, but I'm not sure what's going on though i think it's the correct thing to do.
I want to save the function of SoccerLevelsClass as a member of Button.
Would i do something like this?
//MenuButton.h
#ifndef MenuButton
#define MenuButton
....
class Button
{
public:
Button(void(*SoccerLevelsClass::func)());
void (*SoccerLevelsClass::function)();
....
}
#endif
//MenuButton.cpp
#include <MenuButton.h>
Button::Button(void(*SoccerLevelsClass::func)())
{
function=func; //something like this
}
I know the code is probably way off, but I'd like to know if anybody has any suggestions.
All i really want to know is if it's possible.
Yes, this can be done - either with function pointers like in your example, or with lambdas if you can use C++11.
However, since you want to call a bound function of another class, you would need to pass/store pointer to an instance of that class as well to do that, unless the function is static.
In C++11, this is trivial:
std::function<void(void)> _f;
void apply() {
_f();
}
Bar(void (Foo::* f)()) {
_f = std::bind(f, Foo());
}
In C++03, this is a little tricky. Note in both versions I construct a temporary to call the member function, but I'm not sure whether it is necessary to store an instance of the class.
#include <iostream>
#include <functional>
struct Foo
{
Foo() { }
void stuff() {
std::cout << "hi\n";
}
};
struct Bar
{
void (Foo::* _f)();
void apply() {
(Foo().*_f)();
}
Bar(void (Foo::* f)()) {
_f = f;
}
};
int main()
{
Bar bar(&Foo::stuff);
bar.apply();
}
For what you are trying to do I would use the observer pattern:
class IFootballObserver
{
public:
virtual void OnBallKicked() = 0;
virtual ~IFootballObserver() {}
};
class Fooball
{
public:
Fooball(IFootballObserver& obs)
: mObs(obs)
{
// Call the observer interface at any time like so:
mObs.OnBallKicked();
}
private:
IFootballObserver& mObs;
};
class Button : public IFootballObserver
{
public:
// Football could be passed in/owned by something else
Button() : mFootball(*this) { }
void DoSomething()
{
// Called when foot ball is kicked
}
private:
virtual void OnBallKicked()
{
DoSomething();
}
Fooball mFootball;
};
I find this easier than using function pointers/std::function. Plus you could have a vector of observers and notify many objects of events.

How can 2 different classes point to the same datatable name

I need to initialize an object in a method without specifying the class from where the object is. Can I do that?
can someone give me an example?
EDIT:
MyClass{
...};
MySecondClass
{...
};
void method(*object); //how to write correct??
{..}
MyClass *x= new MyClass();
MySecondClass *y= new MySecondClass();
method(x);
method(y);
Use templates.
template <typename T>
void method(T* object) {
// do stuff with the object, whose real type will be substituted for `T`
}
Templates are a bit complex, so read the chapter in your C++ book on them for more information.
It sounds like you're looking for an interface. You would define an interface that fits the needs of whatever it is that your method is doing.
class MyInterface
{
public:
virtual void doSomething1() = 0;
virtual void doSomething2() = 0;
};
class MyObject : public MyInterface
{
public:
void doSomething1()
{
// Code here
}
void doSomething2()
{
// Code here
}
};
It's somewhat unclear exactly the situation you have b/c you haven't shown any code, but make the method you want to call part of a class. (if it isn't already)
class ClassWithMethod
{
public:
ClassWithMethod(MyInterface &myI)
:x(myI)
{
}
void methodYouUseInjectedObject()
{
// Code
x.doSomething1();
// More code
}
private:
MyInterface &x;
};
Then in you application code where you instantiate the ClassWithMethod, you would "inject" the concrete type of the object you want called.
int main(int argc, char *argv[])
{
MyObject myObject;
ClassWithMethod classMethod(myObject);
// Call the method that will use the injected object.
classMethod.methodYouUseInjectedObject();
return 1;
}
EDIT: (based on updated question)
If you want to create a method that can take two different (and unrelated) objects, but the use the same method signatures you can use a template.
class ClassWithMethod
{
public:
template <class T>
void methodYouUseInjectedObject(T object)
{
T.doSomething();
}
};
This is similar to my approach above except that you do not need to derive your different objects off an interface.
You can use a template.
template<typename T>
void method(T object) {
object.doSomething()
}