1

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

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.

4
  • 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 Sep 24 '20 at 18:46
  • @ErikWeisbrod: See amended answer. – Edgar Bonet Sep 24 '20 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 Sep 25 '20 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 Sep 25 '20 at 17:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.