Klasse erstellt: "no matching function for call" im Konstruktor

Hi,
ich versuche gerade an das ESP32Radio ein 16*2-I2C-LCD dranzubasteln. Das LCD funktioniert mit der LiquidCrystal_I2CLibrary trotz Warnung.
Um manche Funktion etwas bequemer ansteuern zu können, bastel ich mir dazu gerade eine Klasse. Klasse - also "inline" im Quellcode und keine Library mit Headerfile&Co. Das ist das erste mal, dass ich hier für Arduino/C eine Klasse bastel, und ganz ehrlich: im Vergleich zu C# finde ich das ganz schön unübersichtlich und nicht sehr intuitiv, aber naja...

Die Klasse sieht auszugsweise so aus:

class LcdDisplay
{
public:
	int Adress;
	int Cols;
	int Rows;
	LiquidCrystal_I2C I2C_lcd;
	LcdDisplay(int adress, int cols, int rows);
	void init();
	void writeToRow(const char* str, int row);
	void writeToFirstRow(const char* str);
	void writeToSecondRow(const char* str);
};

	LcdDisplay::LcdDisplay(int adress, int cols, int rows)
	{
		Adress = adress;
		Cols = cols;
		Rows = rows;
		I2C_lcd = I2C_lcd(Adress, Cols, Rows);
	}

Nun schmeißt mir die Arduino IDE für die Zeile "LcdDisplay::LcdDisplay(int adress, int cols, int rows)" folgenden Kompilerfehler:

no matching function for call to 'LiquidCrystal_I2C::LiquidCrystal_I2C()'

Prinzipiell müsste sich das ganze auf das initalisieren des Feldes I2C_lcd ein paar Zeilen drunter beziehen. Ich habe im Moment keine Ahnung, wie ich den Fehler interpretieren soll, und google hilft mir jetzt irgendwie auch nicht weiter. Zumindest nicht so, dass ich das Problem verstehe.

Die komplette Ausgabe der IDE lautet:

WARNUNG: Bibliothek LiquidCrystal_I2C behauptet auf [avr] Architektur(en) ausgeführt werden zu können und ist möglicherweise inkompatibel mit Ihrem derzeitigen Board, welches auf [esp32] Architektur(en) ausgeführt wird.
D:\Eigene Dateien\Eigene Dokumente\Arduino\Esp32_radio\Esp32_radio.ino: In constructor 'LcdDisplay::LcdDisplay(int, int, int)':

Esp32_radio:401: error: no matching function for call to 'LiquidCrystal_I2C::LiquidCrystal_I2C()'

LcdDisplay::LcdDisplay(int adress, int cols, int rows)

^

In file included from D:\Eigene Dateien\Eigene Dokumente\Arduino\Esp32_radio\Esp32_radio.ino:100:0:

D:\Eigene Dateien\Eigene Dokumente\Arduino\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:58:3: note: candidate: LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t, uint8_t, uint8_t)

LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows);

^

D:\Eigene Dateien\Eigene Dokumente\Arduino\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:58:3: note: candidate expects 3 arguments, 0 provided

D:\Eigene Dateien\Eigene Dokumente\Arduino\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:56:7: note: candidate: constexpr LiquidCrystal_I2C::LiquidCrystal_I2C(const LiquidCrystal_I2C&)

class LiquidCrystal_I2C : public Print {

^

D:\Eigene Dateien\Eigene Dokumente\Arduino\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:56:7: note: candidate expects 1 argument, 0 provided

D:\Eigene Dateien\Eigene Dokumente\Arduino\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:56:7: note: candidate: constexpr LiquidCrystal_I2C::LiquidCrystal_I2C(LiquidCrystal_I2C&&)

D:\Eigene Dateien\Eigene Dokumente\Arduino\libraries\LiquidCrystal_I2C/LiquidCrystal_I2C.h:56:7: note: candidate expects 1 argument, 0 provided

Esp32_radio:406: error: no match for call to '(LiquidCrystal_I2C) (int&, int&, int&)'

I2C_lcd = I2C_lcd(Adress, Cols, Rows);

^

exit status 1
no matching function for call to 'LiquidCrystal_I2C::LiquidCrystal_I2C()'

Soweit ich das verstehe, beschwert er sich, dass er für den Konstruktor von LiquidCrystal_I2C nicht die passende Anzahl an Parameter hat. Aber das sind genau drei Ints: Adresse, Zeichen, Zeilen - und die habe ich angegeben.
Falls nicht jeder die LiqudiCrystal_I2C kennt, hier der Bespielsketch für's HelloWorld (welcher funktioniert, auch auf dem ESP32!):

//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  lcd.init();                      // initialize the lcd 
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(3,0);
  lcd.print("Hello, world!");
  lcd.setCursor(2,1);
  lcd.print("Ywrobot Arduino!");
   lcd.setCursor(0,2);
  lcd.print("Arduino LCM IIC 2004");
   lcd.setCursor(2,3);
  lcd.print("Power By Ec-yuan!");
}


void loop()
{
}

C++ funktioniert anders als C#. In C++ sieht das so aus

class LcdDisplay
{
public:
  LcdDisplay(int adress, int cols, int rows);
  void init();
  void writeToRow(const char* str, int row);
  void writeToFirstRow(const char* str);
  void writeToSecondRow(const char* str);
private:
  int adress;
  int cols;
  int rows;
  LiquidCrystal_I2C I2C_lcd;
};

LcdDisplay::LcdDisplay(int adress, int cols, int rows) : adress(adress), cols(cols), rows(rows), I2C_lcd(adress, cols, rows)
{
}

Das nennt sich Initialisierungsliste:

Wenn du im Konstruktor bist wurde das I2C_lcd Objekt schon erstellt! Deshalb wird versucht einen Konstruktor ohne Parameter aufzurufen. Aber den gibt es natürlich nicht und entsprechend kommt der Fehler.
Die Initialisierung muss vor dem Konstruktor-Körper erfolgen. Nicht darin.

Public/private solltest du aber auch aus C# kennen. Wobei man das LCD Objekt eventuell public lassen kannst, wenn du doch mal direkt darauf zugreifen willst

Danke.

Wenn du im Konstruktor bist wurde das I2C_lcd Objekt schon erstellt!

Das ist natürlich eine wichtige Information. Das war mir so nicht bekannt. Wie ich sehe ist das ja eher eine Spezialität von C++ und nicht C. Da gibts schon einige Punkte, die man als jemand der, wenn auch nur hobbymässig, eher in C# unterwegs ist, umdenken muss. :wink:

Public/private solltest du aber auch aus C# kennen. Wobei man das LCD Objekt eventuell public lassen kannst, wenn du doch mal direkt darauf zugreifen willst

Ja natürlich. Erstmal alles auf Public zu lassen, ist den ersten Versuchen und der damit verbundenen Unkompliziertheit verbunden.

Ich hoffe ich komme morgen dazu, deine Lösung auszuprobieren!

VG

Abschließendes Feedback:

Hat funktioniert. Danke!