Создать объект-член, используя аргументы конструктора, или передать ссылку на объект через конструктор

c++

Я не совсем уверен в правильности терминологии C++, поэтому я просто проиллюстрирую, чего я пытаюсь достичь, приведя пример Java, поскольку он должен быть довольно очевидным:

public class LcdDecorator {
    private HD44780Lcd lcd;

    public LcdDecorator(int rows, int cols, int i2cAddress) {
        this.lcd = new HD44780Lcd(rows, cols, i2cAddress);
    }
}

или... альтернативно...

public class LcdDecorator {
    private HD44780Lcd lcd;

    public LcdDecorator(HD44780Lcd lcd) {
        this.lcd = lcd;
    }
}

Что бы это ни стоило, на самом деле нет беспокойства по поводу области действия... LcdDecorator — это синглтон, который создается в setup(), затем живет вечно и используется loop() до тех пор, пока не отключится питание.

Вот что я пытался сделать:

LcdFacade.h:

#ifndef CORECONTROLLER_LCDFACADE_H
#define CORECONTROLLER_LCDACADE_H

#include <stdint.h>
#include "../.pio/libdeps/megaatmega2560/HD44780_LCD_PCF8574/src/HD44780_LCD_PCF8574.h"

class LcdFacade {

public:
    LcdFacade(uint8_t rows, uint8_t cols, uint8_t i2cAddress) ;
};

#endif //CORECONTROLLER_LCDFACADE_H

LcdFacade.cpp:

#include "LcdFacade.h"
#include "../.pio/libdeps/megaatmega2560/HD44780_LCD_PCF8574/src/HD44780_LCD_PCF8574.h"

HD44780LCD lcd;

LcdFacade::LcdFacade (uint8_t rows, uint8_t cols, uint8_t i2cAddress) : lcd{rows, cols, i2cAddress} {
    // ... остальная часть конструктора находится здесь ...
}

примечание: я также пытался использовать круглые скобки вместо фигурных скобок для конструктора lcd:

LcdFacade::LcdFacade(uint8_t rows, uint8_t cols, uint8_t i2cAddress) : lcd(rows, cols, i2cAddress) {

В CLion часть lcd{rows, cols, i2caddress} конструктора в LcdFacade.cpp подчеркнута красным, и сообщает, что инициализатор элемента lcd не называет нестатический член данных или базовый класс

Тем временем gcc(?) сообщает об ошибке: нет соответствующей функции для вызова 'HD44780LCD::HD44780LCD() в строке 4 файла LcdFacade.cpp.

Есть идеи?

, 👍1


1 ответ


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

2

Когда вы определяете

HD44780LCD lcd;

в глобальной области вы создаете глобальную переменную, которая инициализируется перед вызовом main(). В этом случае он инициализируется конструктор по умолчанию HD44780LCD::HD44780LCD(), который не существует, отсюда и ошибка. Вы можете избежать этой ошибки, позвонив подходящему конструктор при инициализации, например

HD44780LCD lcd(4, 20, 0x23);

но это может быть неудобно для вас.

Если вы хотите инициализировать lcd в конструкторе LcdFacade, тогда он должен быть нестатическим членом класса:

// В LcdFacade.h:
class LcdFacade {
public:
    LcdFacade(uint8_t rows, uint8_t cols, uint8_t i2cAddress);
private:
    HD44780LCD lcd;  // <- нестатический член
};

// В LcdFacade.cpp:
LcdFacade::LcdFacade(uint8_t rows, uint8_t cols, uint8_t i2cAddress)
: lcd(rows, cols, i2cAddress) {
    ...
}
,