Недопустимое использование нестатической функции-члена
Чтобы объяснить мою проблему, я использовал 3 класса: Actions
, Triggers
и Combine
.
Действия
имитирует функцию действия, определенную извне.
Триггеры
имеют ту функцию, которую необходимо выполнить.
Объединить
объединяет Действия
и Триггеры
.
Теперь void combine_funcs()
является функцией-членом класса Combine
при совпадении между Triggers
и Actions
случиться -> передача функции для выполнения.
Здесь void Combine_funcs()
показан с помощью std::bind
, но он также был протестирован напрямую.
Вывод ошибки приведен ниже кода.
class Actions
{
typedef void (*cb_func)(uint8_t resaon);
private:
cb_func exter_func;
public:
void get_external_func(cb_func func)
{
exter_func = func;
}
void callAction(uint8_t i)
{
exter_func(i);
}
};
class Triggers
{
public:
void this_is_external_func(uint8_t i)
{
Serial.println(i);
}
};
class Combine
{
public:
Actions a;
Triggers b;
void combine_funcs()
{
a.get_external_func(std::bind(&Triggers::this_is_external_func, this,std::placeholders::_1));
}
void loop()
{
if (millis() > 10000)
{
a.callAction();
}
}
};
Combine combo;
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Start!");
combo.combine_funcs();
}
void loop()
{
// put your main code here, to run repeatedly:
combo.loop();
}
Вывод компиляции:
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino: In member function 'void Combine::combine_funcs()':
sketch_jul26a:36:34: error: cannot convert 'std::_Bind_helper<false, void (Triggers::*)(unsigned char), Combine*, const std::_Placeholder<1>&>::type' to 'Actions::cb_func' {aka 'void (*)(unsigned char)'}
36 | a.get_external_func(std::bind(&Triggers::this_is_external_func, this,std::placeholders::_1));
| ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| std::_Bind_helper<false, void (Triggers::*)(unsigned char), Combine*, const std::_Placeholder<1>&>::type
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:9:34: note: initializing argument 1 of 'void Actions::get_external_func(Actions::cb_func)'
9 | void get_external_func(cb_func func)
| ~~~~~~~~^~~~
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino: In member function 'void Combine::loop()':
sketch_jul26a:42:20: error: no matching function for call to 'Actions::callAction()'
42 | a.callAction();
| ^
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:13:8: note: candidate: 'void Actions::callAction(uint8_t)'
13 | void callAction(uint8_t i)
| ^~~~~~~~~~
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:13:8: note: candidate expects 1 argument, 0 provided
exit status 1
cannot convert 'std::_Bind_helper<false, void (Triggers::*)(unsigned char), Combine*, const std::_Placeholder<1>&>::type' to 'Actions::cb_func' {aka 'void (*)(unsigned char)'}
EDIT_1: изменить класс Объединить
, чтобы он наследовал другие классы
class Combine : public Actions, Triggers
{
public:
void combine_funcs()
{
get_external_func(this_is_external_func);
}
void loop()
{
if (millis() > 10000)
{
callAction(13);
}
}
выдает ту же ошибку:
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino: In member function 'void Combine::combine_funcs()':
sketch_jul26a:33:23: error: invalid use of non-static member function 'void Triggers::this_is_external_func(uint8_t)'
33 | get_external_func(this_is_external_func);
| ^~~~~~~~~~~~~~~~~~~~~
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:22:8: note: declared here
22 | void this_is_external_func(uint8_t i)
| ^~~~~~~~~~~~~~~~~~~~~
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino: At global scope:
sketch_jul26a:60:6: error: redefinition of 'void setup()'
60 | void setup()
| ^~~~~
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:46:6: note: 'void setup()' previously defined here
46 | void setup()
| ^~~~~
sketch_jul26a:68:6: error: redefinition of 'void loop()'
68 | void loop()
| ^~~~
/Users/guydvir/Dropbox/Arduino/sketch_jul26a/sketch_jul26a.ino:54:6: note: 'void loop()' previously defined here
54 | void loop()
| ^~~~
exit status 1
invalid use of non-static member function 'void Triggers::this_is_external_func(uint8_t)'
};
@Guy . D, 👍1
Обсуждение1 ответ
Лучший ответ:
Проблема в том, что возвращаемый тип привязки не совпадает с типом исходной функции, поэтому его нельзя установить с помощью void get_external_func(cb_func func)
.
Но это похоже на проблему X->Y. Если вы используете ООП, используйте объекты.
Я рассматриваю набросок в вопросе как тест, поэтому хочу прокомментировать другие части и то, как их правильно сделать. Я только что внес минимальные изменения, чтобы передать объект и вызвать метод (функцию-член) с объектом.
class Triggers
{
public:
void func(uint8_t i)
{
Serial.println(i);
}
};
class Actions
{
Triggers* trigers;
public:
void set_triggers(Triggers* t)
{
trigers = t;
}
virtual void callAction(uint8_t i)
{
trigers->func(i);
}
};
class Combine
{
public:
Actions a;
Triggers b;
void combine_funcs()
{
a.set_triggers(&b);
}
void loop()
{
if (millis() < 10000)
{
a.callAction(1);
}
}
};
Combine combo;
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Start!");
combo.combine_funcs();
}
void loop()
{
// put your main code here, to run repeatedly:
combo.loop();
}
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Массив динамического размера в качестве члена класса
- Как перебрать объекты или передать объект функции?
- Прерывания внутри класса, связанные с функцией класса
- Вызов функций одного класса из другого класса — Обратный вызов
- Зачем хранить значение параметра функции в частной переменной класса?
- Arduino Servo не будет двигаться при использовании классов
- Экземпляры класса внутри другого класса - есть ли способ контролировать количество?
Помогает ли этот Q+A? https://stackoverflow.com/a/72450270/10292145, @VE7JRO
@ VE7JRO, можете ли вы объяснить, зачем мне нужен void* ?, @Guy . D
почему бы не установить объект в качестве параметра?, @Juraj
@Juraj я пытался, но безуспешно, @Guy . D
@guyd - Когда я пытаюсь скомпилировать ваш код, я получаю разные ошибки. Я использую другой компилятор, чем вы, поэтому моя первая ошибка приводит меня сюда: https://stackoverflow.com/questions/14261013/bind-is-not-a-member-of-std В мире Arduino они указывают я здесь: https://forum.arduino.cc/t/include-functional-error/397411 Единственные вопросы, которые у меня есть к вам, это почему вы пишете свой код таким образом и какую проблему вы пытаетесь решить?, @VE7JRO
Почему бы не использовать наследование классов, например,
class Combine public Action {}
? Однако решение в стороне, не создавайте классы ради создания классов, все три ваших класса не нужны или должны принадлежать где-то еще как методы., @hcheungЯ попытаюсь объяснить мою большую проблему: У меня есть 2 класса, которые я написал и протестировал. Один из них — это состояния чтения кнопок, включая класс тайм-аутов, а второй класс связан с включением/выключением индикаторов, включая индикаторы PWM. ОБА используются и тестируются ранее. Третья библиотека сочетает в себе как параметры на флэш-памяти, так и команду MQTT (как своего рода оболочку), даже имеет несколько экземпляров моего третьего класса. Я хочу использовать все свои 3 класса как работающее наследие, а не переписывать все заново., @Guy . D
Я имел в виду, что тип параметра должен быть классом, и вы передаете туда объект и выполняете функцию для этого объекта. функция-член должна быть вызвана для объекта, поэтому вы можете использовать эту функцию в качестве параметра. он не знает, на каком объекте он должен выполняться., @Juraj
@Juraj, можешь объяснить на примере?, @Guy . D
может позже сегодня, @Juraj
Вам нужно вызвать
this_is_external_func()
для объекта, но вы не предоставляете его вcallAction()
. Я вижу две альтернативы: 1) Предоставить объект для вызова метода. 2) Сделать метод функцией класса, которому не нужен объект., @the busybee@hcheung воспользовался вашим советом для inherete (см. редактирование 1), но результаты те же., @Guy . D
возвращаемый тип привязки не совпадает с типом исходной функции, @Juraj
@Juraj Можешь указать?, @Guy . D
Я изменил ваш скетч с помощью
auto f = std:bind....
иa.get_external_func(f);
, и сообщение об ошибке стало немного яснее., @Juraj@Juraj - СУПЕР!!! это был первый вывод, который я получил, что я сделал неправильно., @Guy . D