Составной объект (класс использует класс)
Я хотел бы написать класс, который использует другой класс и его функции-члены. Я узнал, что это композиция объектов, и прочитал несколько примеров того, как это сделать, но это либо не работает для меня, либо я просто не совсем понимаю. Вот части моего кода.
#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
Я не понимаю, зачем такое переопределение. Кто-нибудь может мне это объяснить?
@Erik Weisbrod, 👍1
1 ответ
Лучший ответ:
ошибка: в классе 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, но не в обоих одновременно.
- Как правильно поместить дескриптор u8g2 в класс
- Передача ссылки на оборудование между методами в пользовательском классе
- Использование класса внутри другого класса
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Ошибка: "недопустимое использование нестатической функции-члена" при вызове функции из моего собственного класса-метода
- Как приглушить фоновые светодиоды на TFT дисплее с помощью ILI9341
- Массив динамического размера в качестве члена класса
- Кнопка двойного состояния Nextion
Спасибо, Эдгар, за объяснение. Вы правы, это не композиция, а отсылка. Ваш совет по добавлению члена данных решил ошибку с отсутствующим полем. Я обновил свой код в вопросе. Теперь у меня проблема с переопределением. Вы можете помочь мне?, @Erik Weisbrod
@ErikWeisbrod: см. ответ с поправками., @Edgar Bonet
Спасибо Эдгар еще раз, теперь код компилируется. Я не знал о возможности использовать встроенный конструктор в заголовочном файле. Если я определяю конструктор в файле ccp. мне все еще нужен TriangleButton в заголовке?, @Erik Weisbrod
@ErikWeisbrod: Если вы _определяете_ конструктор в файле .cpp, вам все равно нужно _объявить_ его в определении класса в заголовочном файле:
TriangleButton (список параметров...);
. Обратите внимание, что в объявлении нет ни списка инициализации (например,: _tft(tft)
), ни тела функции ({}
), и оно заканчивается точкой с запятой (;
)., @Edgar Bonet