c++ указатель на нестатические функции-члены
Я прочитал много сообщений и ответов об указателях на нестатические функции-члены, но ни один из них не может решить мою проблему.
Поэтому я создал короткий пример, чтобы повторить мою проблему здесь: даже если этот пример может быть "решен" различными способами, для окончательного программного обеспечения важно сохранить структуру, как в Примере, спасибо.
Это заголовок класса " Funcs.h":
class Funcs
{
private:
double a = 1, b = 2;
public:
Funcs();
~Funcs();
double Fun1(double X);
double solver(double X0);
double aaa(double(*fun)(double), double x0);
};
Это cpp класса " Funcs.cpp":
#include "Funcs.h"
using namespace std;
Funcs::Funcs()
{
}
Funcs::~Funcs()
{
}
double Funcs::Fun1(double X) {
double f1 = a*X;
return f1;
}
double Funcs::solver(double X0)
{
double result;
result = aaa(Fun1, X0);
return result;
}
double Funcs::aaa(double(*fun)(double), double x0)
{
return fun(x0);
}
И, Наконец, это и есть главное " главное.cpp":
#include <iostream>
#include "Funcs.h"
using namespace std;
int main() {
double x0=1;
double result;
Funcs funcs;
result = funcs.solver(x0);
cout << result << endl;
return 0;
}
Ошибка находится в методе Funcs:: solver, когда я вызываю " result = aaa (Fun1, X0);", потому что я не могу использовать указатель на Fun1, потому что это нестатический член. В то же время я не могу сделать его статическим, иначе переменная "a" не могла бы быть видна внутри статического метода.
Заранее благодарю за помощь.
3 ответа:
Проблема заключается в том, что вы пытаетесь передать указатель на функцию-член, в то время как ожидается, что указатель либо на функцию-член, либо на статическую функцию-член. И это разные типы.
Здесь " fun " - это указатель на функцию:
double(*fun)(double)
.И здесь это указатель на функцию-член класса Funcs:
double(Funcs::*fun)(double)
Итак, вот как вы можете изменить свой код, чтобы заставить его работать.
class Funcs { // all the rest is the same double aaa(double(Funcs::*fun)(double), double x0); }; double Funcs::solver(double X0) { // ... result = aaa(&Funcs::Fun1, X0); // ... } double Funcs::aaa(double(Funcs::*fun)(double), double x0) { return (this->*fun)(x0); }
Смотрите живой примерв Coliru .
Это может быть прекрасный способ пойти если вы хотите намеренно ограничить свой метод
aaa
, чтобы принимать только функции-членыFuncs
какfun
. Если вы также хотите передать функции, не являющиеся членами, или, например, лямбды вaaa
, рассмотрите возможность использованияstd::function
вместо этого.
Ваша проблема заключается в том, что указатель на функцию не совпадает с указателем на функцию-член. Прочитайте this для получения дополнительной информации и this для чистого способа записи указателя на функции-члены. Если вам нужно сохранить эту структуру, сделайте aaa статической или не являющейся членом функцией, которая принимает все, что ей нужно в качестве аргументов, или измените первый аргумент aaa на
double(Funcs::*)(double)
вместоdouble(*fun)(double)
. Вы даже можете перегрузить aaa для поддержки обоих видов использования.
На самом деле
Funcs::Fun1
не являетсяdouble(*)(double)
.Любой нестатический метод имеет такую сигнатуру:
return_type(*)(class_type* this, arguments...)
Давайте рассмотрим точные типы:
//first argument of `aaa` has type double(*)(double) double aaa(double(*fun)(double), double x0); double Funcs::Fun1(double X) { double f1 = a*X; return f1; } // Fun1 has type double(Funs::*)(double) // i.e it's a method of Funs and it takes (implicitly) first argument // which is `this` pointer // so that how `aaa` must look like double aaa(double(Funs::*fun)(double), double x0) { // special sytax *this.*fun(x0); } // and that how `solver` looks like double Funcs::solver(double X0) { double result; // get pointer to method result = aaa(&Funs::Fun1, X0); return result; }
Если вы не знакомы с указателями на методы-проверьте this