Видимость функций.
- Войдите на сайт для отправки комментариев
Сб, 03/10/2020 - 19:15
Есть программа, которая в цикле должна перебирать массив указателей на функции и вызывать данные функции, получая от них значения. Я сильно упростил код, просто для понимания, почему выдает ошибку при компиляции. Ошибка такая: test_pointer:17:27: error: 'can1' was not declared in this scope float (*pScan[3])() = {can1, can2, can3};
Есть 3 файла - сам скетч, заголовочный .h и .cpp. Создан класс TEST. Когда помещаю функции can1(), can2(), can3() в сам скетч, то ошибки нет. Но мне нужно чтобы функции находились в описании класса. Почему не видны имена функций в строке float (*pScan[3])() = {can1, can2, can3}; ?
файл скетча:
#include "test_pointer.h"
float dataSensors[3];
TEST test;
void setup()
{
Serial.begin(115200);
while (!Serial);
}
void loop()
{
float (*pScan[3])() = {can1, can2, can3};
for(int i = 0; i < 3; i++){
dataSensors[i] = pScan[i]();
Serial.print("Sensor" + String(i+1));
Serial.print(" Value= ");
Serial.print(dataSensors[i]);
}
Serial.println();
delay(1000);
}
Файл test_pointer.h:
class TEST{
public:
float can1();
float can2();
float can3();
};
Файл test_pointer.cpp :
#include "test_pointer.h"
float TEST::can1(){
return 12.7;
}
float TEST::can2(){
return 43.5;
}
float TEST::can3(){
return 66.7;
}
Так нельзя, потому что при вызове метод не будет относиться ни к какому экземпляру класса. Используй std::function и лямбды
Благодарю! Но я начинающий и придется изучить эти 2 новые темы- пространство имен и лямбдя-выражения))
Да не нужны Вам никакие лямбды, и уж тем более std - он Вас троллит!
Вы лучше ответьте на два вопроса.
1. Вам точно надо, чтобы Ваши can1/can2/can3 были методами класса?
2. Если да, то второй вопрос - их точно незя сделать статическими методами?
Ответьте, и я покажу Вам как это делается. Неохота показывать то, что не пригодится.
Судя по случаю с "ICMP 3,4" не троллит, а просто пишет абы чо. От великого ума или по глупости - вопрос, конечно, дискуссионный.
я в указателях ничего не понимаю,. но если бы даже что-то понимал то
float (*pScan[3])() = {test.can1, test.can2,test.can3};Троллит тот, кто пишет "не нужен std".
я в указателях ничего не понимаю,. но если бы даже что-то понимал то
float (*pScan[3])() = {test.can1, test.can2,test.can3};В общем, да, но скорее всего нарвётесь на варнинг и, главное, смысл? Что Вам это даст?
не, не откомпилируется...что-то мне в этой конструкции тоже не нравится, визуально
адрес 16-ти битный, указатель аналогично, с флоатами тут что-то не то
Как все, (акромя ТС) возбудились-то!
В общем, blokerun2, мне уходить надо, не буду ждать Вашего ответа.
Вызывать нестатическую функцию-член вне контекста экземпляра не имеет смысла (даже если удастся). Вы же не можете просто взять анализ там крови, Вы всегда берёте его у кого-то! Так и Ваша can1 - она не существует сама по себе - она существует только у какого-то конкретного экземпляра класса TEST.
Поэтому брать указатель (смещение) можно просто на метод класса TEST (без указания экземпляра), а вот вызывать можно только в контексте экземпляра.
В Вашей программе есть экземпляр test, вот в контексте его и надо вызывать.
Я сделал минимальные изменения в Вашей программе - разбирайтесь (остальные файлы не менялись).
#include "test_pointer.h" float dataSensors[3]; TEST test; // // Определим тип - указатель на член класса TEST // (можно и без него, но запись будет сложнее) typedef float (TEST::* MemberPointer)(void); void setup(void) { Serial.begin(57600); while (!Serial); } void loop() { // Определяем массив казателей на члены класса TEST can1, can2 и can3 MemberPointer pScan[3] = { & TEST::can1, & TEST::can2, & TEST::can3 }; for(int i = 0; i < 3; i++) { // Вызываем фкнуцию-член в контексте экземпляра как положено dataSensors[i] = (test.*pScan[i])(); Serial.print("Sensor" + String(i+1)); Serial.print(" Value= "); Serial.print(dataSensors[i]); } Serial.println(); delay(1000); }Только, вот убей Бог, не могу понять нафига Вам это! Более того, уверен, что реально-то и не нужно, просто костыль пытаетесь присобачить.
не, не откомпилируется...что-то мне в этой конструкции тоже не нравится, визуально
А, ну да, я не заметил, у Вас же в левой части тип неправильный
dataSensors[i] = (test.*pScan[i])();
Так, конечно же, на фиг не нужно. Связал с экземпляром в вызывающем коде, потерял абстракцию.
dataSensors[i] = (test.*pScan[i])();
Так, конечно же, на фиг не нужно. Связал с экземпляром в вызывающем коде, потерял абстракцию.
так покажите, как нужно, например как здесь
#1
Глянул - идиоты из ардуино вырезали <functional> для avr. Тут замена https://github.com/khoih-prog/functional-vlpp
Связал с экземпляром в вызывающем коде, потерял абстракцию.
Сами то поняли, что сказали?