Задать вопрос

Как получить указатель на метод объекта?

Можно ли в C++ получить указатель на метод класса, как на обычную функцию, чтоб можно было позже вызвать его, явно передав указатель на объект?
  • Вопрос задан
  • 1346 просмотров
Подписаться 3 Оценить Комментировать
Решения вопроса 2
Можно
Если напрямую, то надо использовать тип "указатель на функцию член" вида Ret (Class::*)(Args...) [const]. Сам указатель получать &Class::Fun, а вызывать операторами .* или ->*
Или использовать std::function (boost::function), std::bind (boost::bind) или std::mem_fun, std::mem_fn для более унифицированного подхода:

struct some
{
	some() : value(0) {}

	int inc() { return ++value; }
	int dec() { return --value; }
	int get() const { return value; }

	int value;
};

int main()
{
	some s;

	int (some::*inc_f)() = &some::inc; // inc_f - указатель на функцию
	std::cout << "(s.*inc_f)() = " << (s.*inc_f)() << std::endl; // оператор .* - оператор вызова по указателю на функцию
	int (some::*val_ptr) = &some::value; // val_ptr - указатель на член
	s.*val_ptr = 10;
	std::cout << "s.*val_ptr = " << s.*val_ptr << std::endl;

	int (some::*const_f)() const = &some::get; // const-функция
	std::cout << "s.*const_f() = " << (s.*const_f)() << std::endl;

	using namespace std::placeholders;
	std::function<int (some&)> mem_f;
	
	mem_f = std::bind(&some::inc, _1); // биндим на функцию-член, _1 - placeholder для объекта
	std::cout << "mem_f(s) = " << mem_f(s) << std::endl; // s.inc();
	mem_f = std::mem_fn(&some::dec); // другой способ через mem_fn
	std::cout << "mem_f(s) = " << mem_f(s) << std::endl; // s.dec();

	std::function<int()> mem_f_ = std::bind(&some::inc, &s); // биндим на функцию член и сразу указываем объект, получаем функцию без аргументов
	std::cout << "mem_f_() = " << mem_f_() << std::endl; /// s.inc();

	std::function<int(some const &)> const_fn = std::mem_fn(&some::get); // some const &
	std::cout << "const_fn(s) = " << const_fn(s) << std::endl;

    return 0;
}
Ответ написан
Комментировать
@sitev_ru
sitev.ru - мой блог ...
Можно cpp.sh/9crs

#include <iostream>
#include <functional>

class Form {

};

class Form1 : public Form {
public:
	void click() const {
		std::cout << "Form1::click" << std::endl;
	}
};

typedef std::function<void(const Form1*)> ClickEvent;

class Button {
public:
	ClickEvent onClick;
	Form1 *owner;

	Button(Form1 *owner) {
		this->owner = owner;
	}
	void click() {
		if (onClick != NULL) onClick(owner);
	}
};

int main()
{
	Form1 *a = new Form1();
	Button btn(a);

	btn.onClick = std::mem_fn(&Form1::click);

	btn.click();
}


Надо разобраться, как сделать универсально, чтобы ClickEvent работало с любым классом, в не только как тут Form1
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы