C++ anropa funktion i ett objekts subobjekt

Permalänk
Medlem

C++ anropa funktion i ett objekts subobjekt

Skulle behöva lite hjälp med C++ och hur man ska tänka här. Det verkar inte fungera på samma sätt som i annan OOP.
En parentes är att det gäller Arduino (ATMega328P), men utvecklas i C++ i Visual Studio Code.

Är inte så van vid C++ så har dålig koll på minnespekare och hur länge saker finns kvar i minnet.

this->gameEngine->display->displayLines(displayLines);

Vid kompilering ger det följande felmeddelande:

\src\GameMenu.cpp: In member function 'void GameMenu::DrawMenu()': \src\GameMenu.cpp:296:30: error: invalid use of incomplete type 'class Display' this->gameEngine->display->displayLines(displayLines); ^~ In file included from \src\GameMenu.cpp:3:0: /include/GameEngine.h:15:7: note: forward declaration of 'class Display' class Display; ^~~~~~~ \src\GameMenu.cpp:296:32: error: invalid use of incomplete type 'class Display' this->gameEngine->display->displayLines(displayLines); ^~~~~~~~~~~~ In file included from \src\GameMenu.cpp:3:0: /include/GameEngine.h:15:7: note: forward declaration of 'class Display' class Display; ^~~~~~~

efter lite sökning på nätet så verkade det inte gå att göra. Har fastnat lite mitt tänkande och vet inte riktigt hur jag ska komma vidare.

(Jag har tagit bort onödig kod från klasserna i det här exemplet)

class GameEngine { public: Display *display; // Wrapper class for LCD display GameMenu *gameMenu; }

class Display { public: void displayLines( String _displayLines[4] ); }

class GameMenu { private: GameEngine * gameEngine; // Parent

Att jag har en referens i GameMenu till GameEngine är för att komma åt föräldern.

i GameMenu-klassen finns metoden DrawMenu som bygger upp texten som ska visas i LCD-displayen.

void GameMenu::DrawMenu() { ... this->gameEngine->display->displayLines(displayLines); }

Det kanske är feltänkt och bara borde generera en text som returneras och inte ska ha tillgång till själva Display-objektet?

Permalänk
Medlem

Det handlar inte om anropet eller användandet av pekaren i sig, utan att c++ kräver att alla klasser och funktioner deklareras innan de används.

Vanligen görs detta högst upp i .cpp filen, eller helst i en separat headerfil (.h) som inkluderas högst upp i filen.

Läs på lite om headerfiler och deklarering
https://docs.microsoft.com/en-us/cpp/cpp/header-files-cpp?vie...

Permalänk
Medlem
Skrivet av Ziron:

Det handlar inte om anropet eller användandet av pekaren i sig, utan att c++ kräver att alla klasser och funktioner deklareras innan de används.

Vanligen görs detta högst upp i .cpp filen, eller helst i en separat headerfil (.h) som inkluderas högst upp i filen.

Läs på lite om headerfiler och deklarering
https://docs.microsoft.com/en-us/cpp/cpp/header-files-cpp?vie...

Ah, det var så enkelt att jag missat att inkludera Display.h i GameMenu.h
Efter att jag nu ändrade det så försvann felmeddelandet

Permalänk
Medlem

Felet är att du bara har en "forward declaration" i GameEngine.h, du måste inkludera Display.h någonstans så att kompilatorn faktiskt hittar definitionen av Display-klassen om du vill kunna använda klassen. Du kan ha pekare och referenser till forward-deklarerade klasser, men så fort du vill komma åt instansen de pekar på så måste hela klassdefinitionen vara synlig för kompilatorn.

Om display ska vara en publik medlem av GameEngine så är det mest lämpligt att inkludera Display.h direkt i GameEngine.h och ta bort forward-deklarationen. Ett annat alternativ är att inkludera Display.h i alla .cpp-filer du använder display i, men det är mer användarvänligt att se till att GameEngine.h inkluderar sina egna beroenden.