So we have some class (i.e. Button) and its method which takes void function.
Also we have parent class State which has static method buttonAction used to asign
to Button instance. Problem is State's child class must have an option to override
static method buttonAction and this method must be assigned to button by parent class State constructor.
It must work something like this:
Code:
MyState st;
button.click();
Desired output:
MyState::buttonAction!
But instead I get:
State::buttonAction!
Related .cpp file:
#include <iostream>
#include <cstdio>
class Button
{
public:
void setAction(void(*foo)(void));
void click();
private:
void(*foo)(void);
};
void Button::setAction(void(*foo)(void)) { this->foo = foo; }
void Button::click() { this->foo(); }
Button button;
class State
{
public:
State();
private:
static void buttonAction();
};
State::State()
{
button.setAction(this->buttonAction); // pointer to state's buttonAction
}
void State::buttonAction()
{
printf("State::buttonAction!");
};
class MyState : State
{
private:
static void buttonAction(); // overridden buttonAction
};
void MyState::buttonAction()
{
printf("MyState::buttonAction!");
};
int main() {
MyState st;
button.click();
return 0;
}
Have MyState's constructor override it:
MyState::MyState()
{
button.setAction(&buttonAction)l
}
After the superclass initially invokes setAction() to point the callback to its own static class function, this will override it, and repoint it to MyState's static class function.
Related
I have a optional property event that I define as a pointer in this struct:
struct AnimatedSprite {
//...some other properties
Event *event;
};
Let's say I want to store a StartTransitionEvent , defined like this:
class Event {
public:
Event() = default;
};
class StartTransitionEvent: public Event {
public:
int test = 1;
};
I can create and assign the StartTransitionEvent:
auto sprite = AnimatedSprite{};
auto newEvent = StartTransitionEvent{};
sprite.event = &newEvent;
But how do I get the type once I need to call something like:
eventBus->EmitEvent<StartTransitionEvent>(sprite->event);
Should I do some sort of checking on my event pointer to get to the StartTransitionEvent? Or maybe not use pointers at all and go for a std::variant to store the event with all it's possible child-classes?
You could use double dispatch, a.k.a. visitor pattern and let the specific Event visit the EventBus.
So something like
class Event
{
public:
virtual void Emit(EventBus& eventBus) = 0;
};
class StartTransitionEvent : public Event
{
public:
void Emit(EventBus& eventBus) override
{
eventBus.EmitEvent(this);
}
};
sprite.event.Emit(eventBus);
Assuming you're designing such a hierarchy, your EventBus class should be able to work with the base Event class. You achieve that through virtual functions in the Event class:
struct Event {
Event() = default;
virtual ~Event() = default;
virtual void action1(); // event-specific actions
virtual void action2();
virtual void action3();
};
struct StartTransitionEvent : Event {
void action3() override; // override some actions
};
struct EventBus {
void emit(Event& event) {
// ...
event.action1();
// ...
event.action2();
// ...
event.action3();
}
};
int main() {
StartTransitionEvent event;
EventBus bus;
bus.emit(event);
}
I am writing an Arduino program where LEDs and a bunch of other electronics are controlled by different buttons. To simplify the code, I am using the Observer Mode:
class Observer observes EventThrowers, who performs check() every frame and notifies Observers if necessary. The code definition for Observer and EventThrower looks like this:
class Observer {
public:
virtual void handleEvent(int label, bool state) = 0; // Virtual method called by EventThrowers.
};
class EventThrower {
private:
std::vector<Observer *> observer_list;
protected:
void notifyObservers(int label, bool state) {
for (Observer *observer : observer_list) {
observer->handleEvent(label, state);
}
}
public:
virtual void check() = 0; // Virtual method used in loop() for frame checking.
void addObserver(Observer *_observer) {
this->observer_list.push_back(_observer);
}
};
And my LEDCtrl class (an Observer) and ButtonClick class (an EventThrower) definitions are:
class LEDCtrl : public Observer {
public:
// properties
LEDCtrl(int _led_pin) { ... } // constructor
void handleEvent(int label, bool state) { ... } // overridden handleEvent method
private:
void toggleLight(bool new_status) { ... } // assistant method
};
class ButtonClick : public EventThrower {
public:
// properties
ButtonClick(int _button_pin, int _default, int _label) { ... } // constructor
void check() { ... } // overridden check() that is called every frame to check the status of the button and choose to notify Observers or not
};
My initialization of a LEDCtrl-ButtonClick instance pair looks like:
ButtonClick *buttonClick1 = new ButtonClick(BUTTON1, 0, 0);
LEDCtrl *ledCtrl1 = new LEDCtrl(LED1);
buttonClick1->addObserver(ledCtrl1);
However, the above code throws this compile error:
error: 'buttonClick1' does not name a type
buttonClick1->addObserver(ledCtrl1);
^~~~~~~~~~~~
How can I fix this?
As the title says I have the following "base" class that user can extend:
class BaseScene
{
private:
bool sceneloop = false;
public:
virtual void Start();
virtual void EventHandler(SDL_Event event);
virtual void Update();
virtual void Draw();
void _toggleLoopMode() { sceneloop = !sceneloop; }
bool _sceneloop() { return sceneloop; }
};
My problem is I can't know what name, the user, choose for his classes so how I can call a known method (like Start or EventHandler) from my main class inside an unknown class?
An example of a class that is unknown to me but well-known to the user can be:
class SomeFunnyRandomName : public BaseScene
{
public:
void Start();
void Eventhandler(SDL_Event event);
void Update();
void Draw();
};
So form the main class I need to call Start() inside "SomeFunnyRandomName" without:
SomeFunnyRandomName sfrn = new SomeFunnyRandomName();
If you can include the code it will be very helpful (but not required).
You take a reference or pointer to BaseScene, and call the methods on that. The caller passes an instance of their derived class.
class UsesScene {
BaseScene & scene;
public:
UsesScene(BaseScene & scene) : scene(scene) {}
void doStuff() { scene.Start(); scene.Update(); }
/*... etc*/
};
int main() {
SomeFunnyRandomName scene;
UsesScene usesScene(scene);
usesScene.doStuff();
}
I have a parent class that invokes a callback that is abstract. The child class is meant to override this callback, but must never call it on its own from its code.
class Parent(){
public:
void Init(){ MyCallback(); }
protected:
virtual void MyCallback() = 0;//child must override, but child must never call it manually.
};
class Child : public Parent{
protected:
void MyCallback()override{ }
private:
void SomeCode{ MyCallback(); }//<---how to prevent this?
}
There are many callbacks such as these. I don't want the user to get lost and think that he should call any of them manually.
Is it possible to prevent these callbacks from being invoked by child class?
I don't think there is a way to enforce the rules you want at compile-time, but you can enforce them at runtime via assertion-failures, which is the next-best thing, since at least anyone who breaks the rule will learn the error of their ways the next time they run the program. Note that I've added a requirement that the subclass-overrides of MyCallback() must call up to the superclass-method exactly once, to prevent subclasses from gratuitously making additional calls to MyCallback() on themselves or their superclasses inside the callbacks-are-allowed context.
#include <stdio.h>
#include <stdlib.h>
class Parent
{
public:
Parent() : _okayToCallCount(0), _numParentClassCallsMade(0) {/* empty */}
protected:
virtual void MyCallback()
{
if (_okayToCallCount == 0) {printf("MyCallback() was called from an invalid context!\n"); abort();}
_numParentClassCallsMade++;
if (_numParentClassCallsMade > 1) {printf("Parent::MyCallback() was called more than once from the subclass's override-method!\n"); abort();}
}
private:
// This is the only place that MyCallback should EVER be called from!
void TheOnlyPlaceThatMyCallbackShouldEverBeCalledFrom()
{
_numParentClassCallsMade = 0;
_okayToCallCount++;
MyCallback();
_okayToCallCount--;
if (_numParentClassCallsMade < 1) {printf("Parent::MyCallback() was never called from the subclass's override-method!\n"); abort();}
}
int _okayToCallCount;
int _numParentClassCallsMade;
};
class Child : public Parent
{
public:
Child() {}
void SomeCode() { MyCallback(); }//<---how to prevent this?
protected:
virtual void MyCallback()
{
Parent::MyCallback(); // REQUIRED!
}
};
int main(int argc, char ** argv)
{
Child c;
c.SomeCode();
return 0;
}
Your Program had soo many mini Errors
class Parent(){ // These braces**()** don't come after a class's name
public:
void Init(){ MyCallback(); }
protected: // Because the datatype is protected, it can't be accessed properly (overrided) by **Main Function**
virtual void MyCallback() = 0;//child must override, but child must never call it manually.
};
class Child : public Parent{
protected:
void MyCallback()override{ }
private:
void SomeCode{ MyCallback(); }//<---how to prevent this? // You forgot the braces here **()**
} // You forgot the semi-colon **;**
Here I have fixed them for you:-
#include <iostream>
using namespace std;
class Parent {
public:
void Init(){ MyCallback(); }
//protected:
virtual void MyCallback() = 0;//child must override, but child must never call it manually.
};
class Child : public Parent{
protected:
void MyCallback()override{ cout <<"Child Class Function!"; }
private:
void SomeCode() { MyCallback(); }//<---how to prevent this?
};
int main()
{
Parent* ptr_base;
Child derived;
ptr_base = &derived;
ptr_base->MyCallback();
}
I am trying to pass a pointer to memeber of class(Dialog::handler) from its method(in scope of Dialog::render) to some outer method(Button::OnClick).
Here is a small example:
class Button
{
public:
void OnClick(void (*handler)())
{
handler();
}
};
class Dialog
{
public:
void handler()
{
//do stuff
}
void render()
{
auto button = new Button;
//Source of problem
button->OnClick(this->*handler);
}
};
But compiler shows error:
non-standard syntax; use '&' to create a pointer to member
Also I triend other combinations, like:
this->handler.
&this.handler.
this.*handler.
etc
But obviously they failed.
You could use std::function and pass it a lambda in which you've caught this of the object you'd like to call back:
#include <functional>
#include <iostream>
class Button {
public:
void OnClick(std::function<void()> handler) {
handler();
}
};
class Dialog {
public:
void handler() {
std::cout << "Dialog::handler\n";
}
void render() {
auto button = new Button;
// a lambda catching "this" Dialog.
button->OnClick([this] { this->handler(); });
delete button; // you didn't delete your button
}
};
int main() {
Dialog d;
d.render();
}
But it looks like you should probably inherit from a common base class that has a virtual void handler() so you can pass object pointers/references around instead. A rough idea:
#include <iostream>
class VisualBase {
public:
virtual void handler() = 0;
virtual ~VisualBase() = 0;
};
VisualBase::~VisualBase() {}
class Button : public VisualBase {
public:
void handler() override {}
void OnClick(VisualBase* caller) {
caller->handler();
}
};
class Dialog : public VisualBase {
public:
void handler() override {
std::cout << "Dialog::handler\n";
}
void render() {
Button button;
button.OnClick(this);
}
};
int main() {
Dialog d;
d.render();
}