Composición de objetos (clase usa clase)

Sep 23 2020

Me gustaría escribir una clase que utilice otra clase y sus funciones miembro. Descubrí que esto es composición de objetos y leí algunos ejemplos de cómo hacerlo, pero no me funciona o simplemente no lo entiendo completamente. Aquí hay partes de mi código.

#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

Quiero usar un objeto Adafruit_TFTLCD y sus funciones miembro dentro de mi propia clase TriangleButton. El objeto tft se inicializa antes de la configuración.

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); //Class is part of SPFD5408_Adafruit_TFTLCD.h

Construí TriangleButton.h similar a este hilo ( Usar objeto de otra clase dentro de la clase ) y usé una referencia al objeto tft.

/*
  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

En el ccp. puse un constructor correspondiente.

TriangleButton::TriangleButton(Adafruit_TFTLCD &tft, int16_t coordX, int16_t coordY, int16_t orientation, uint16_t size, uint16_t color)
:
_tft(tft)

Ahora recibo el siguiente mensaje de error:

C: \ Users \ Erik \ Documents \ Arduino \ libraries \ AquariumController_Library \ TriangleButton.cpp: 19: 1: error: redefinición de 'TriangleButton :: TriangleButton (Adafruit_TFTLCD &, int16_t, int16_t, int16_t, uint16_utton), uint16_tton (Adafruit_TFTLCD & tft, int16_t coordX, int16_t coordY, int16_t orientación, uint16_t tamaño, uint16_t color) ^ ~~~~~~~~~~~~~ En archivo incluido desde C: \ Users \ Erik \ Documents \ Arduino \ libraries \ AquariumController_Library \ TriangleButton.cpp: 7: 0: C: \ Users \ Erik \ Documents \ Arduino \ libraries \ AquariumController_Library \ TriangleButton.h: 14: 5: nota: 'TriangleButton :: TriangleButton (Adafruit_TFTLCD &, int_16_t, int16_TFTLCD &, int_t16_t, , uint16_t) 'definido anteriormente aquí TriangleButton (Adafruit_TFTLCD & tft, int16_t coordX, int16_t coordY, int16_t orientación, uint16_t size, uint16_t color): _tft (tft) {} ^ ~~~~~~~~~~~~~~ estado de salida 1

No entiendo por qué hay una redefinición. ¿Alguien me lo puede explicar?

Respuestas

1 EdgarBonet Sep 23 2020 at 19:02

error: la clase 'TriangleButton' no tiene ningún campo llamado '_tft'

Esto debería explicarse por sí mismo. Cuando escribes en el constructor

_tft(tft)

Significa “inicializar la propiedad _tftde este objeto con el parámetro tft.

No está muy claro qué quiere decir con "composición de objetos". En el sentido habitual, significa que el objeto A es o tiene un objeto B. En su caso, parece que desea TriangleButtontener una referencia a un Adafruit_TFTLCD. Esto no es realmente una composición, ya que su clase no tiene ni tiene una pantalla LCD.

Como solución inmediata, simplemente agregue un miembro de datos apropiado a la clase:

Adafruit_TFTLCD &_ftf;

Suponiendo que tener una referencia a la pantalla LCD es realmente lo que desea para su clase, esto debería ser suficiente para resolver su problema.


Editar : para responder a la pregunta editada.

“Redefinición” significa que está definiendo de nuevo algo que ya se ha definido antes. En este caso, el constructor se define en línea en el archivo de encabezado:

TriangleButton(Adafruit_TFTLCD &tft,
        int16_t coordX, int16_t coordY,
        int16_t orientation, uint16_t size, uint16_t color)
    : _tft(tft){}

(sí, esa es una definición completa con un cuerpo vacío).

Y luego intenta definirlo nuevamente en el archivo cpp. Esto es un error, cada método debe definirse solo una vez. A su elección, puede estar en línea en el encabezado o en el .cpp, pero no en ambos.