Составной объект (класс использует класс)

class tft object-oriented

Я хотел бы написать класс, который использует другой класс и его функции-члены. Я узнал, что это композиция объектов, и прочитал несколько примеров того, как это сделать, но это либо не работает для меня, либо я просто не совсем понимаю. Вот части моего кода.

#include <SPFD5408_Adafruit_GFX.h>    // Базовая графическая библиотека
#include <SPFD5408_Adafruit_TFTLCD.h> // Аппаратно-зависимая библиотека
#include <SPFD5408_TouchScreen.h>     // Сенсорная библиотека
#include <TriangleButton.h>        // библиотека TriangleButton

Я хочу использовать объект Adafruit_TFTLCD и его функции-члены внутри моего собственного класса TriangleButton. Объект tft инициализируется перед установкой.

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); //Класс является частью SPFD5408_Adafruit_TFTLCD.h

Я создал файл TriangleButton.h, аналогичный этому потоку (Использовать объект другого класса в классе), и использовал ссылку на объект tft.

/*
  TriangleButton.h - библиотека для создания и чтения треугольных кнопок.
*/
#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

В КПК. я поставил соответствующий конструктор.

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

Теперь я получаю следующее сообщение об ошибке:

C:\Users\Erik\Documents\Arduino\libraries\AquariumController_Library\TriangleButton.cpp:19:1: error: переопределение '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, размер uint16_t, цвет uint16_t) ^~~~~~~~~~~~~~ В файле, включенном из C:\Users\Erik\Documents\Arduino\libraries\AquariumController_Library\TriangleButton.cpp:7:0: C:\Users\Erik\Documents\Arduino\libraries\AquariumController_Library\TriangleButton.h:14:5: примечание: 'TriangleButton::TriangleButton(Adafruit_TFTLCD&, int16_t, int16_t, int16_t, uint16_t, uint16_t)' ранее определено здесь TriangleButton(Adafruit_TFTLCD &tft, int16_t coordX, int16_t coordY, int16_t ориентация, uint16_t размер, uint16_t цвет): _tft(tft){} ^~~~~~~~~~~~~~ статус выхода 1

Я не понимаю, зачем такое переопределение. Кто-нибудь может мне это объяснить?

, 👍1


1 ответ


Лучший ответ:

0

ошибка: в классе TriangleButton нет поля с именем _tft

Это должно быть понятно. Когда вы пишете в конструкторе

_tft(tft)

Это означает «инициализировать свойство _tft этого объекта с параметр tft.

Не очень понятно, что вы подразумеваете под «композицией объектов». В обычном смысле это означает, что объект A либо является, либо имеет объект B. В вашем случае, похоже, вы хотите, чтобы ваш TriangleButton содержал ссылку на Adafruit_TFTLCD. Это не совсем композиция, как ваш класс ни не, ни нет ЖК-дисплея.

В качестве немедленного решения просто добавьте соответствующий член данных в класс:

Adafruit_TFTLCD &_ftf;

Предположим, что ссылка на ЖК-дисплей действительно нужна вам. вашего класса, этого должно быть достаточно, чтобы решить вашу проблему.


ОБНОВЛЕНИЕ: чтобы ответить на отредактированный вопрос.

«Переопределение» означает, что вы снова определяете то, что уже были определены ранее. В этом случае конструктор определяется встроенным в заголовочный файл:

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

(да, это полное определение с пустым телом).

А затем вы пытаетесь снова определить его в файле cpp. Это ошибка, каждый метод должен быть определен только один раз. На ваш выбор может быть либо в заголовке, либо в .cpp, но не в обоих одновременно.

,

Спасибо, Эдгар, за объяснение. Вы правы, это не композиция, а отсылка. Ваш совет по добавлению члена данных решил ошибку с отсутствующим полем. Я обновил свой код в вопросе. Теперь у меня проблема с переопределением. Вы можете помочь мне?, @Erik Weisbrod

@ErikWeisbrod: см. ответ с поправками., @Edgar Bonet

Спасибо Эдгар еще раз, теперь код компилируется. Я не знал о возможности использовать встроенный конструктор в заголовочном файле. Если я определяю конструктор в файле ccp. мне все еще нужен TriangleButton в заголовке?, @Erik Weisbrod

@ErikWeisbrod: Если вы _определяете_ конструктор в файле .cpp, вам все равно нужно _объявить_ его в определении класса в заголовочном файле: TriangleButton (список параметров...);. Обратите внимание, что в объявлении нет ни списка инициализации (например, : _tft(tft)), ни тела функции ({}), и оно заканчивается точкой с запятой (;)., @Edgar Bonet