tMenu menu0(10,20);
tMenu* name = &menu0;
name->init();
alternativ:
tMenu menu0(10,20);
tMenu & name = menu0;
name.init();
hallo
ein neues Klassen-Problem:
ich habe eine
Ich möchte die aktuell behandelte Instanz jetzt immer als aliasCode:class tMenu { protected: public: tMenu(int a, int b) { } int test; void init() {} }; // und 3 (oder auch deutlich mehr) Instanzen tmenu menu0, menu02, menu23;
actMenu
ansprechen, in der Art
actMenu = menu0;
actMenu.init(); // initialisiert menu0
actMenu.test=123; // setzt jetzt menu0.test=123
(Also selbe Syntax als wäre das alias eine reale Instanz)
und später auch ein weiteres alias für den Vorgänger:
preMenu = menu0;
actMenu = menu02;
wobei dann wieder Zugriffe erfolgen sollen z.B. als
actMenu.test=999; // setzt jetzt menu02.test=999
für die "neue aktuelle" Instanz
Später dann je nach Programmfluss wieder neue willkürliche actMenu und preMenu Verweise, entweder dann eben menu23 oder auch wieder menu0.
Wie kann man diesen alias-Verweis-Mechanismus richtig programmieren?
Über Pointer * oder Pointeradressen & oder beides ?
Geändert von HaWe (07.12.2018 um 16:21 Uhr)
tMenu menu0(10,20);
tMenu* name = &menu0;
name->init();
alternativ:
tMenu menu0(10,20);
tMenu & name = menu0;
name.init();
dankeschön für die schnelle Antwort!
Beide super, das zweite sogar noch einen Tick besser, da nur ein . und kein -> nötig!
Vielen Dank nochmals!
- - - Aktualisiert - - -
hm - klappt noch nicht ganz:
ich habe initialisiert:
aber bei den aktuellen Zuweisungen klappt es noch nicht:Code:// global: tMenu menu0(10,20); tMenu menu02(10,20); tMenu & actMenu = menu0; tMenu & preMenu = menu0;
&actMenu = menu02; // error: exit status 1 lvalue required as left operand of assignment
Geändert von HaWe (07.12.2018 um 16:42 Uhr)
Zeig mal deinen genauen Code. Ich glaube du hast wieder ein Copy Pastefehler
tMenu & actMenu = menu0; <-- Da ist gar kein menu02.
Edit:
Als Beispiel:
Code:// Example program #include <iostream> #include <string> class test { public: int a; }; int main() { test instance; test & aliasTest = instance; } Getestet mit: http://cpp.sh/ Geht auch global: // Example program #include <iostream> #include <string> class test { public: int a; }; test instance; test & aliasTest = instance; int main() { std::cout << instance.a << std::endl; aliasTest.a = 10; std::cout << aliasTest.a << std::endl; }
ich hatte es nur nachträglich geändert, zur Verdeutlichung, aber das menu02 ist auch da.
Der vollständige Code ist ein wenig erweitert gegenüber dem gekürzten Beispiel - hoffe, es ist nicht zuviel
Code:// I2C #include <Wire.h> // Incl I2C comm, but needed for not getting compile error #define ESPSDA D2 // defaults #define ESPSCL D1 // // TFT //#include <Adafruit_SSD1306.h> #include <ESP_SSD1306.h> // Modification of Adafruit_SSD1306 for ESP8266 compatibility #include <Adafruit_GFX.h> // Needs a little change in original Adafruit library (See README.txt file) #include <Fonts/FreeSans12pt7b.h> // #include <Fonts/FreeSansBold12pt7b.h> // #include <Fonts/FreeSans9pt7b.h> // #include <Fonts/FreeMono12pt7b.h> // #include <Fonts/FreeMono9pt7b.h> // Pin definitions //---------------------------------------------------------------------------- // display driver //---------------------------------------------------------------------------- #define OLED_RESET 10 // GPIO10=D12 Pin RESET signal (virtual) //Adafruit_SSD1306 display(OLED_RESET); //Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET); ESP_SSD1306 display(OLED_RESET); //---------------------------------------------------------------------------- // ButtonClass buttons //---------------------------------------------------------------------------- #include <ButtonClass.h> // 3 buttons for menu control tButton btn0; tButton btn1; tButton btnfx; //---------------------------------------------------------------------------- // OLED menu //---------------------------------------------------------------------------- class tMenu { protected: int16_t MENULEN, LINELEN, VISLNUM, FONTHI; char buf[20]; int8_t firstvln, lastvln, displn; public: int16_t ID, pre_ID; int8_t act, pre_act; char **list; int test; tMenu (int16_t menulen, int16_t linelen, int16_t id) // constructor { firstvln=0; lastvln=0; displn=0; pre_ID=0; act=0; pre_act=0; MENULEN = menulen; // number of available menu options LINELEN = linelen; // line length of menu options ID = id; list = new char*[MENULEN]; for(int i = 0; i < MENULEN; i++) { list[i] = new char[LINELEN+1]; } } void init(int16_t vislnum=5, byte fonthi=13 ) { // ()=defaults=(5,13) for(int i=0; i<MENULEN; i++) { sprintf(buf,"%d .......|", i); strncpy(list[i], buf, LINELEN); VISLNUM = vislnum; // number of visible menu options FONTHI = fonthi; } } void mdisplay() { if(act>VISLNUM-1) firstvln=_min(act-1, MENULEN-VISLNUM); else firstvln=0; lastvln=firstvln+VISLNUM-1; display.clearDisplay(); for(byte i=firstvln; i<=lastvln; i++) { displn=(FONTHI-3) + (i-firstvln)*FONTHI; if(i==act) { display.setCursor(0, displn); display.print('>'); Serial.print('>'); } else Serial.print(' '); Serial.println(list[i]); display.setCursor(11, displn); display.print(list[i]); } display.display(); Serial.println(); } int32_t checkbtn(int8_t btop, int8_t bbtm, int8_t bfunc) { if(btop==1){ // dec if(act>0) act--; //Serial.print ("^"); Serial.println(act); mdisplay(); return 11 ; } if(btop==3){ // min act=0; //Serial.print ("^"); Serial.println(act); mdisplay(); return 13 ; } if(bbtm==1){ // inc if(act<MENULEN-1) act++; //Serial.print ("v"); Serial.println(act); mdisplay(); return 21; } if(bbtm==3){ // max act=MENULEN-1; //Serial.print ("v"); Serial.println(act); mdisplay(); return 23; } if(bfunc==1){ sprintf(buf,"Menu %d-%d ToDo=%d", ID,act,bfunc); Serial.println(buf); return 1; } if(bfunc==2){ sprintf(buf,"Menu %d-%d ToDo=%d", ID,act,bfunc); Serial.println(buf); } if(bfunc==3){ sprintf(buf,"Menu %d-%d ToDo=%d", ID,act,bfunc); Serial.println(buf); return 3; } return 0; } ~tMenu() { // destructor // Dynamically delete the array delete[] list ; } }; tMenu menu0(10,20, 0); // numEntries, lineLength, menuID; tMenu menu02(10,20, 2); tMenu & actMenu = menu0; tMenu & preMenu = menu0; //---------------------------------------------------------------------------- // OLED dashboard //---------------------------------------------------------------------------- void dashboard(byte mode) { display.clearDisplay(); display.setFont(); if (mode == 0) { display.setFont(); // h=8.0 pt display.setCursor( 0, 0); display.print(" 0 Hello World 1"); } display.display(); display.setFont(); } void setup(void) { // Start Serial //pinMode(D3, OUTPUT); // + LED_BUILTIN btn0.init(D6, INPUT_PULLUP, 50); btn1.init(D3, INPUT_PULLUP, 50); btnfx.init(D4, INPUT_PULLUP, 50); //pinMode(D7, OUTPUT); //pinMode(D8, OUTPUT); Serial.begin(115200); delay(2000); // wait for Serial() Serial.println("Serial started"); // Start Wire (SDA, SCL) //Wire.begin(ESPSDA,ESPSCL); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Wire.begin(); // SSD1306 Init display.begin(SSD1306_SWITCHCAPVCC); // Switch OLED //display.begin(SSD1306_SWITCHCAPVCC, 0x3D, true, false); display.setRotation(2); display.clearDisplay(); // Clear the buffer. // text display tests display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Hello, world!"); display.display(); //-------------------------------------- // test + debug Serial.println(); for(byte i=0; i<10; i++) { Serial.print("-"); Serial.println(menu0.list[i]); } menu0.init(); // optional numVisibleLines, fontHeight; defaults = (5,13) display.clearDisplay(); display.display(); display.setFont(&FreeMono9pt7b); // h=13.10pt menu0.mdisplay(); } void loop() { int32_t result; result = menu0.checkbtn(btn0.click(), btn1.click(), btnfx.click() ); &actMenu = menu02; // test }
Geändert von HaWe (07.12.2018 um 17:23 Uhr)
tMenu menu0(10,20, 0); // numEntries, lineLength, menuID;
tMenu menu02(10,20, 0);
tMenu & actMenu = menu0;
tMenu & preMenu = menu0;
Du machst dort defintiv keine Zuweisung auf menu02.
Und da solltest du dir noch mal C++ Grundlagen durchlesen https://www.tutorialspoint.com/cplus...references.htm
&actMenu = menu02;
Wenn dann:
actMenu = menu02;
nein, oben nicht, aber in loop
Beim Initialisieren nur auf menu0 initialisiert,
erst in loop wird testweise actmenu auf menu2 initialisiert.
- - - Aktualisiert - - -
moment....
- - - Aktualisiert - - -
ergibt jetzt völlig korrektCode:tMenu menu0(10,20, 0); // numEntries, lineLength, menuID; tMenu menu02(10,20, 2); tMenu & actMenu = menu0; tMenu & preMenu = menu0; void setup() { menu0.init(); // optional numVisibleLines, fontHeight; defaults = (5,13) Serial.println(menu0.ID); Serial.println(actMenu.ID); actMenu.mdisplay(); actMenu = menu02; // test actMenu.init(); Serial.println(menu02.ID); Serial.println(actMenu.ID); actMenu.mdisplay();
super, habs kapiert, dankeschön!Code:0 0 >0 .......| 1 .......| 2 .......| 3 .......| 4 .......| 2 2 >0 .......| 1 .......| 2 .......| 3 .......| 4 .......|
- - - Aktualisiert - - -
noch ein unerwarteter bug im Programm:
bis nach der 1. Zuweisung actMenu=menu0 ist noch alles ok,Code:tMenu menu0(10,20, 0); // numEntries, lineLength, menuID=0; tMenu menu02(10,20, 2); // numEntries, lineLength, menuID=2; tMenu & actMenu = menu0; tMenu & preMenu = menu0; void init() { // display.setFont(&FreeMono9pt7b); // h=13.10pt display.clearDisplay(); display.display(); Serial.println("Menu 0+02 init:"); menu0.init(); strcpy(menu0.list[0], " menu0"); Serial.print("menu0.ID="); Serial.println(menu0.ID); //<<<<<<<<<< stimmt noch !! menu02.init(); strcpy(menu02.list[0], " menu02"); Serial.print("menu02.ID="); Serial.println(menu02.ID); //<<<<<<<<<< stimmt noch !! Serial.println(); Serial.println("actMenu-Zuweisungen:"); Serial.println(); actMenu=menu0; Serial.println("actMenu=0"); Serial.print("menu0.ID="); Serial.println(menu0.ID); // noch ok Serial.print("menu02.ID="); Serial.println(menu02.ID); Serial.print("actMenu.ID="); Serial.println(actMenu.ID); actMenu.mdisplay(); // noch ok Serial.println("actMenu=02"); actMenu = menu02; // test Serial.print("menu0.ID="); Serial.println(menu0.ID); // Fehler Serial.print("menu02.ID="); Serial.println(menu02.ID); Serial.print("actMenu.ID="); Serial.println(actMenu.ID); actMenu.mdisplay(); Serial.println("actMenu=0"); actMenu = menu0; // und wieder zurück Serial.print("menu0.ID="); Serial.println(menu0.ID); // Fehler Serial.print("menu02.ID="); Serial.println(menu02.ID); Serial.print("actMenu.ID="); Serial.println(actMenu.ID); // Fehler actMenu.mdisplay(); // Fehler delay(1);
nach der Neuzuweisung actMenu=menu02 ist der Inhalt von Original-menu0 überschrieben:
Code:Menu 0+02 init: menu0.ID=0 // ok! menu02.ID=2 // ok! actMenu-Zuweisungen: actMenu=0 menu0.ID=0 // ok! menu02.ID=2 actMenu.ID=0 > menu0 // ok 1 .......| 2 .......| 3 .......| 4 .......| actMenu=02 menu0.ID=2 // Fehler! menu02.ID=2 actMenu.ID=2 > menu02 // ok 1 .......| 2 .......| 3 .......| 4 .......| actMenu=0 menu0.ID=2 // Fehler! menu02.ID=2 actMenu.ID=2 // Fehler! > menu02 // Fehler! 1 .......| 2 .......| 3 .......| 4 .......|
Geändert von HaWe (07.12.2018 um 18:58 Uhr)
ob ich schon wieder betriebsblind gegen eigene dumme Fehler bin...?
oh -
das ist ja Mist... :-/Once a reference is initialized to an object, it cannot be changed to refer to another object. Pointers can be pointed to another object at any time.
Dann probiere ich es vlt doch mal so
tMenu menu0(10,20);
tMenu* name = &menu0;
name->init();
oder vlt fällt mir auch noch was ganz anderes ein, mit Steuerung direkt aus dem Objekt heraus
- ich brauche ja eh eine längere verkettete Liste von Vorgängern und Nachfolgern
Lesezeichen