Ошибка преобразования типа в указателе на функцию-член класса

Здравствуйте, это обновление этот предыдущий вопрос я сделал

Я пытался выполнить функцию по указателю внутри класса (содержание класса не имеет отношения к моей проблеме).

Это был код, размещенный на предыдущем вопросе:

сообщение об ошибке:

cannot convert ‘Clip::func’ from type ‘void (Clip::)(std::string) {aka void (Clip::)(std::basic_string<char>)}’ to type ‘callback {aka void (*)(std::basic_string<char>)}’

Clip.h

void func(string str){
cout << str << endl;
}

Clip.cpp

void Clip::update(){
typedef void(*callback)(string);
callback callbackFunction = func;
callbackFunction("called");
}

——Решение, которое я нашел ——


Я и мой друг провели небольшое исследование, чтобы найти способ обойти эту ситуацию, и это то, что мы нашли. Даже при том, что это работает, у нас есть некоторые сомнения относительно задействованных выражений (вопросы в конце поста)

Clip.h

    typedef  void (Clip::*Callback) (string);
void func(string _val);

Clip.cpp

void Clip::update(){
Callback function;
function = &Clip::func;
(this->*function)("a");
}

Вопросы:

a- в предыдущем посте @tkausl ответил: «… указатели на функции-члены не совместимы с (не-членами) указателями на функции». Это причина того, что другой код не работает внутри какого-либо класса (даже если этот класс полностью пуст)?

б- почему необходимо объявить указатель так: Клип :: * Обратный звонок если мы уже внутри класса Clip?

c- Что означает это выражение ?: это -> функция *

d- есть ли более простой способ или выражение для этого же требования?

заранее спасибо.

1

Решение

Вы действительно столкнулись указатели на функции-члены. Они аналогичный обычные указатели на функции, но более нюансированные, потому что (нестатические) функции-члены всегда неявно имеют специальные this переданный им параметр, который ссылается на текущий объект, для которого была вызвана функция. Этот секрет this Параметр строго типизируется в соответствии с классом, содержащим функцию. Вот почему имя класса также является частью указателя на тип функции-члена. Это также причина, по которой они не смешиваются с обычными указателями функций. Вот основной пример:

// Declaration of a pointer to member function
// Note that no object is used here
void (ClassName::*my_fn_pointer)(ParameterTypes);

// Assignment also doesn't use an object
my_pointer = &ClassName::exampleMemberFunction;

// But to invoke the method, you need an object
ClassName obj;
(obj::*my_fn_pointer)(example_params);

// Alternatively, inside a member function of ClassName:
(this->*my_fn_pointer)(example_params);

Есть много альтернатив. Я не вижу остальной части вашего кода и какую проблему вы пытаетесь решить, поэтому мой совет ограничен. Я бы, однако, одобрил использование std::function с лямбды:

// std::function generically wraps a callable type
std::function<void(ParamTypes)> my_fn;// Using an object:
ClassName obj;
// lambda declaration
my_fn = [&obj](ParamTypes params){
// 'obj' is captured by reference, so make sure it stays alive as long as needed
obj.chooseYourMemberFunctionHere(params);
};

// function is called here, syntax is easier on the eyes
my_fn(example_params);// Using 'this' inside a member function:
my_fn = [this](ParamTypes params){
// 'this' is captured by reference
// also make sure the current object stays alive alive as long as needed
this->chooseYourMemberFunctionHere(params);
};

my_fn(example_params); // function is called here
1

Другие решения

Это не имеет никакого отношения к тому, где вы пишете свой код. Указатель на функцию-член и указатели на функции — это два разных типа указателей. Ваш код не работает, потому что вы не можете назначить указатель на функцию-член обычному указателю на функцию. Если бы было возможно рассмотреть этот кусок кода, что должно быть на его выходе?

class Foo
{
public:
Foo(int x) :x(x) {}
void bar(int y)
{
std::cout << x+y;
}
int x;
}
int main()
{
typedef void(*callback)();

callback ptr = &Foo::bar;//Won't compile with same error as in your question

ptr(5);
}

Там нет ни одного случая Foo так что нет x печатать. В отличие от C # C ++ не позволит вам захватить this, так Foo f; callback ptr = &f::bar тоже не скомпилируется. Вы можете думать о Foo::bar эквивалентно

void bar(Foo* this,int y)
{
std::cout<< this->x+y;
}

И теперь вы видите, что эти типы функций действительно разные.

Вы можете увидеть сверху bar перевод этого типа this должно быть указано, не имеет значения, где вы пишете этот код.

Вызов функции-члена осуществляется через ->* оператор, его левая часть точно отсутствует this Указатель и правая часть — это переменная-указатель функции-члена и аргументы. Увидеть:

Foo foo;
typedef void(Foo::callback)(int);//Member pointer
callback ptr = &Foo::bar;//Now OK
Foo* thisFoo = &foo;//Left-hand side must be a pointer to Foo
(thisFoo->*ptr)(5);//equivalent to foo->bar(5);

this->*function Просто означает вызов функции-члена, хранящейся в function переменная и использовать this указатель как экземпляр.

Какое требование? Преобразование не может быть сделано. Есть хакерский способ с шаблонными функциями и локальными статическими переменными, который работает, если вы знаете, что в каждый момент будет только один обратный вызов, назначенный для типа. В противном случае старайтесь не использовать их, есть более безопасные альтернативы с лямбдами и std::function доступны, которые могут связывать this в моде c # ссылка на сайт

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector