Composição de objetos (classe usa classe)

Sep 23 2020

Eu gostaria de escrever uma classe que utiliza outra classe e suas funções-membro. Descobri que isso é composição de objetos e li alguns exemplos de como fazer, mas ou não funciona para mim ou simplesmente não entendo completamente. Aqui estão partes do meu 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

Eu quero usar um objeto Adafruit_TFTLCD e suas funções de membro dentro de minha própria classe TriangleButton. O objeto tft é inicializado antes da configuração.

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

Eu construí o TriangleButton.h semelhante a este thread ( Use objeto de outra classe dentro da classe ) e usei uma referência ao 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

No ccp. eu coloquei um construtor correspondente.

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

Agora recebo a seguinte mensagem de erro:

C: \ Users \ Erik \ Documents \ Arduino \ libraries \ AquariumController_Library \ TriangleButton.cpp: 19: 1: erro: redefinição de 'TriangleButton :: TriangleButton (Adafruit_TFTLCD &, int16_t, int16_t, int16_t, uint16_tiangleButton :: TriangleButton (Adafruit_TFTLCD &, int16_t, int16_t, int16_t, uintiangleButton' TriangleButton: (Adafruit_TFTLCD & tft, int16_t coordX, int16_t coordY, orientação int16_t, tamanho uint16_t, cor uint16_t) ^ ~~~~~~~~~~~~~~ No arquivo incluído em 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_t16_t16_t, int16_t16_t, int16_t, , uint16_t) 'definido anteriormente aqui TriangleButton (Adafruit_TFTLCD & tft, int16_t coordX, int16_t coordY, orientação int16_t, tamanho uint16_t, cor uint16_t): _tft (tft) {} ^ ~~~~~~~~~~~~~~ Status de saída 1

Não entendo porque é uma redefinição. Alguém pode me explicar?

Respostas

1 EdgarBonet Sep 23 2020 at 19:02

erro: a classe 'TriangleButton' não possui nenhum campo chamado '_tft'

Isso deve ser autoexplicativo. Quando você escreve no construtor

_tft(tft)

Significa “inicializar a propriedade _tftdeste objeto com o parâmetro tft.

Não está muito claro o que você entende por “composição de objetos”. No sentido usual, significa que o objeto A é ou tem um objeto B. No seu caso, parece que você deseja TriangleButtonmanter uma referência a um Adafruit_TFTLCD. Isso não é realmente composição, já que sua classe não é nem tem um LCD.

Como solução imediata, basta adicionar um membro de dados apropriado à classe:

Adafruit_TFTLCD &_ftf;

Supondo que segurar uma referência para o LCD é realmente o que você deseja para sua classe, isso deve ser o suficiente para resolver seu problema.


Editar : Para responder à pergunta editada.

“Redefinição” significa que você está definindo novamente algo que já foi definido antes. Nesse caso, o construtor é definido inline no arquivo de cabeçalho:

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

(sim, essa é uma definição completa com um corpo vazio).

E então você tenta defini-lo novamente no arquivo cpp. Isso é um erro, cada método deve ser definido apenas uma vez. De acordo com sua escolha, pode ser embutido no cabeçalho ou no .cpp, mas não ambos.