How to pass pointer to a member within class to outer class?

138 Views Asked by At

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.

1

There are 1 best solutions below

4
Ted Lyngmo On BEST ANSWER

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();
}