I would like to write a class which utilises another class and it ́s member functions. I found out that this is object composition and read some examples of how to do it but it ither doesn ́t work for me or I just don ́t understand it completely. Here are parts of my code.
#include <SPFD5408_Adafruit_GFX.h> // Core graphics library
#include <SPFD5408_Adafruit_TFTLCD.h> // Hardware-specific library
#include <SPFD5408_TouchScreen.h> // Touch library
#include <TriangleButton.h> // TriangleButton library
I want to use an Adafruit_TFTLCD object and its member functions inside my own class TriangleButton. The object tft is initialised before setup.
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); //Class is part of SPFD5408_Adafruit_TFTLCD.h
I built the TriangleButton.h similar to this thread (Use object of other class within class) and used a reference to the tft object.
/*
TriangleButton.h - Library for for constructing and reading triangle Buttons.
*/
#ifndef TriangleButton_h
#define TriangleButton_h
#include "Arduino.h"
#include <SPFD5408_Adafruit_TFTLCD.h>
class TriangleButton
{
public:
TriangleButton(Adafruit_TFTLCD &tft, int16_t coordX, int16_t coordY, int16_t orientation, uint16_t size, uint16_t color) : _tft(tft){}
boolean IsTriggered();
void dash();
private:
Adafruit_TFTLCD &_tft;
int16_t _coordX;
int16_t _coordY;
int16_t _orientation;
int16_t _size;
int16_t _color;
int16_t _ru;
int16_t _hc;
};
#endif
In the ccp. i put a coresponding constructor.
TriangleButton::TriangleButton(Adafruit_TFTLCD &tft, int16_t coordX, int16_t coordY, int16_t orientation, uint16_t size, uint16_t color)
:
_tft(tft)
Now i get the following error message:
C:\Users\Erik\Documents\Arduino\libraries\AquariumController_Library\TriangleButton.cpp:19:1: error: redefinition of 'TriangleButton::TriangleButton(Adafruit_TFTLCD&, int16_t, int16_t, int16_t, uint16_t, uint16_t)' TriangleButton::TriangleButton(Adafruit_TFTLCD &tft, int16_t coordX, int16_t coordY, int16_t orientation, uint16_t size, uint16_t color) ^~~~~~~~~~~~~~ In file included from C:\Users\Erik\Documents\Arduino\libraries\AquariumController_Library\TriangleButton.cpp:7:0: C:\Users\Erik\Documents\Arduino\libraries\AquariumController_Library\TriangleButton.h:14:5: note: 'TriangleButton::TriangleButton(Adafruit_TFTLCD&, int16_t, int16_t, int16_t, uint16_t, uint16_t)' previously defined here TriangleButton(Adafruit_TFTLCD &tft, int16_t coordX, int16_t coordY, int16_t orientation, uint16_t size, uint16_t color) : _tft(tft){} ^~~~~~~~~~~~~~ exit status 1
I don`t understand why ther is a redefinition. Can somebody explain it to me?
1 Answer 1
error: class 'TriangleButton' does not have any field named '_tft'
This should be self-explanatory. When you write in the constructor
_tft(tft)
It means "initialize the property _tft
of this object with the
parameter tft
.
It is not very clear what you mean by "object composition". In the usual
sense, it means that object A either is or has an object B. In your
case, it seems like you want your TriangleButton
to hold a reference
to an Adafruit_TFTLCD
. This is not really composition, as your class
neither is nor has an LCD.
As an immediate solution, just add an appropriate data member to the class:
Adafruit_TFTLCD &_ftf;
Assuming that holding a reference to the LCD is really what you want for your class, this should be enough to solve your issue.
Edit: To answer the edited question.
"Redefinition" means you are defining again something that has already been defined before. In this case, the constructor is defined inline in the header file:
TriangleButton(Adafruit_TFTLCD &tft,
int16_t coordX, int16_t coordY,
int16_t orientation, uint16_t size, uint16_t color)
: _tft(tft){}
(yes, that's a complete definition with an empty body).
And then you try to define it again in the cpp file. This is an error, every method should be defined only once. At your choosing, it can be either inline in the header or in the .cpp, but not both.
-
Thank you Edgar for your explaination. You are right this is not a composition but a reference. Your advice of adding the data member solved the error with the missing field. I updated my code in the question. Now i have a problem with a redefinition. Can you help me?Erik Weisbrod– Erik Weisbrod2020年09月24日 18:46:10 +00:00Commented Sep 24, 2020 at 18:46
-
@ErikWeisbrod: See amended answer.Edgar Bonet– Edgar Bonet2020年09月24日 18:49:54 +00:00Commented Sep 24, 2020 at 18:49
-
Thank you Edgar once again now the code compiles. I did not know about the possibility to use an inline constructor in the header file. If i define the constructor in the ccp. do i still need the TriangleButton in the header?Erik Weisbrod– Erik Weisbrod2020年09月25日 16:25:59 +00:00Commented Sep 25, 2020 at 16:25
-
@ErikWeisbrod: If you define the constructor in the .cpp file, you still have to declare it in the class definition within the header file:
TriangleButton(parameter list...);
. Note that the declaration has no initialization list (i.e.: _tft(tft)
) nor a function body ({}
), and it ends with a semicolon (;
).Edgar Bonet– Edgar Bonet2020年09月25日 17:10:14 +00:00Commented Sep 25, 2020 at 17:10