Uniwersalność klasy, uruchamianie funkcji z (char)Nazwa funkcji

0

Witam,
zamierzam napisać klase do obsługi programu, i sęk w tym że niektóre komendy używam z klasy, niektóre nie. Klasa ma być uniwersalna. Tutaj cały kod, od razu mówię że nie szukam gotowca, tylko idei, nazwy funkcji, gdyż póki co projekt jest w fazie projektowania.

#include <PCF8574.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>

byte adresTermometru[8] = {0x28, 0xFF, 0xB, 0xCC, 0x64, 0x14, 0x2, 0x43};
byte adresExpandera = 0x38;
boolean TablicaZCyframi[10][7] = 
  {
  {LOW,LOW,LOW,HIGH,LOW,LOW,LOW},
  {LOW,HIGH,HIGH,HIGH,LOW,HIGH,HIGH},
  {LOW,LOW,HIGH,LOW,HIGH,LOW,LOW},
  {LOW,LOW,HIGH,LOW,LOW,LOW,HIGH},
  {LOW,HIGH,LOW,LOW,LOW,HIGH,HIGH},
  {HIGH,LOW,LOW,LOW,LOW,LOW,HIGH},
  {HIGH,LOW,LOW,LOW,LOW,LOW,LOW},
  {LOW,LOW,HIGH,HIGH,LOW,HIGH,HIGH},
  {LOW,LOW,LOW,LOW,LOW,LOW,LOW},
  {LOW,LOW,LOW,LOW,LOW,LOW,HIGH}
  };

int pinTermometru = 11;
int PinKropki = 4;
int pinPrzesuwajacyATMEGA = 2;
int temperatura, dziesietna, jednosci,analogowyOdczytFotoRezystora,natezenieSwiataWProcentach;
boolean jezeliGuzikJestNacisniety;

PCF8574 expander;
OneWire onewire(pinTermometru);
DallasTemperature sensors(&onewire);

void setup() {
  
  sensors.begin();
  sensors.setResolution(adresTermometru, 9);
  
  expander.begin(adresExpandera);
  for(int i = 0;i<8;i++){
    pinMode(i+pinPrzesuwajacyATMEGA, OUTPUT);
    expander.pinMode(i, OUTPUT);
  }
  
  digitalWrite(PinKropki+pinPrzesuwajacyATMEGA, LOW);
  expander.digitalWrite(PinKropki, HIGH);
  
}

void NarysujCyfre(int CyfraDoWyswietlenia, char Wyjscie, int PinZaczynajacy =0){
  int pin = 0+PinZaczynajacy;
  if(Wyjscie == (char)'Ekspander'){
    for(int i = 0;i<7;i++){
      if(pin == PinKropki) pin++;
      expander.digitalWrite(pin, TablicaZCyframi[CyfraDoWyswietlenia][i]);
      pin ++;
    }
    
  }else if(Wyjscie == (char)'ATMEGA'){
    
    for(int i = 0;i<7;i++){
      if(pin == PinKropki+PinZaczynajacy) pin++;
      digitalWrite(pin, TablicaZCyframi[CyfraDoWyswietlenia][i]);
      pin ++;
    }
    
  }
}
void loop() {
    jezeliGuzikJestNacisniety = analogRead(1) > 1000;
    if(jezeliGuzikJestNacisniety){
      analogowyOdczytFotoRezystora = analogRead(A0);
      if(analogowyOdczytFotoRezystora > 500) analogowyOdczytFotoRezystora = 500;
      
      natezenieSwiataWProcentach = map(analogowyOdczytFotoRezystora, 0, 500, 0, 99);
      dziesietna = (int)(natezenieSwiataWProcentach/10);
      jednosci = (int)(natezenieSwiataWProcentach -(dziesietna*10));
      
      NarysujCyfre(dziesietna,'Ekspander');
      NarysujCyfre(jednosci,'ATMEGA',pinPrzesuwajacyATMEGA);
      delay(250);
    }else{
      sensors.requestTemperatures(); 
      temperatura = sensors.getTempCByIndex(0);
      dziesietna = (int)(temperatura/10);
      jednosci = (int)(temperatura -(dziesietna*10));
      
      NarysujCyfre(dziesietna,'Ekspander');
      NarysujCyfre(jednosci,'ATMEGA',pinPrzesuwajacyATMEGA);
      delay(250); 
    }
}

Tutaj przykład. Mamy do obsługi funkcje z standardowej biblioteki i z dodatkowej, która może mieć też różne nazwy funkcji.

for(int i = 0;i<8;i++){
    pinMode(i+pinPrzesuwajacyATMEGA, OUTPUT);
    expander.pinMode(i, OUTPUT);
  }

Czyli dla pierwszego struktura wyglądała by dość oczywisto.

LEDDisplay(int PoczatkowyPin,int OstatniPin,int PinKropki); //na konstruktor.

Lecz dla dodatkowej biblioteki chciałbym zrobić coś ala.

LEDDisplay(int PoczatkowyPin,int OstatniPin,int PinKropki,char 'Nazwa klasy');

Teraz użyć funkcji z klasy, którą podałem w konstruktorze(oczywiście parametry z konstruktora bym zcachował i uruchomił później. Przykład takiej funkcji expander.begin(adresExpandera);

obiektLEDDisplay.appendInit(char 'Nazwa funkcji', char 'Parametry');

No i dalej uzupełnić resztę funkcji, gdyż nie każda nazwa pokrywa się z funkcjami w standardowej bibliotece, typu zamiast digitalWrite, jest Write lub Write8, wszystko zależy od klasy, a są różne.

obiektLedDisplay.replaceFunction(char 'Nazwa Oryginalnej Funkcji',char 'Docelowa Nazwa funkcji');

Pozdrawiam
Michał Szałapski

0

Strasznie to opisałeś.

jeśli dobrze rozumiem, chcesz uruchomić jakaś funkcję na podstawie jej nazwy lub wręcz stworzyć jakiś obiekt na podstawie nazwy klasy.
Niestety w standardowym C++ nie ma meta danych, które pozwoliłby to zrobić w miarę prosto is szybko (z Qt takie dane są dostępne). W standardowym C++ musiałbyś dodatkowo sam tworzyć te dane co jest dość pracochłonne.

IMO jednak powinieneś opisać chcesz osiągnąć, bo prawie na pewno nie jest ci potrzebna taka armata (częsty problem przy stawianiu pytanie przez początkujących), tymczasem kulawo opisałeś jak coś chcesz zrobić i nie wiadomo po co.

0

Witam,
tutaj masz np. przykład wywołania funkcji w języku PHP

public function foo($method,$argument)
{
     //safety first - you might not need this if the $method
     //parameter is tightly controlled....
     if (method_exists($this, $method))
     {
         return $this->$method('Hello World');//this.{nazwa funkcji w zmiennej}(argument);
     }
     else
     {
         //oh dear - handle this situation in whatever way
         //is appropriate
         return null;
     }
}

Tutaj schemat
this.{nazwa funkcji w zmiennej}(argument);
Czyli chodzi o coś takiego, tylko w tym przypadku trzeba byłoby jakoś rozszerzyć klasę LEDDisplay o tą dodatkową.
Albo tutaj, troszke łatwiejszy do zrozumienia kod
http://php.net/manual/en/function.call-user-func.php
przykład 3 i 4

$classname = "myclass";

call_user_func(array($classname, 'say_hello'));
call_user_func($classname .'::say_hello'); // As of 5.2.3

$myobject = new myclass();

call_user_func(array($myobject, 'say_hello'));

Albo coś takiego

$method_name = "AMethodName";

$obj = new ClassName();

$obj->{$method_name}();

1 użytkowników online, w tym zalogowanych: 0, gości: 1