C++ 无法为自定义 class 类型创建变量

C++ unable to create variable for custom class type

我已经开始了一个 arduino 项目,我想将我的代码包装成某种 classes 以保持它的简单性和可维护性。

我创建了一个 class 来处理 LCD I2C 屏幕,我称之为 ScreenManager。

ScreenManager.h

#ifndef Morse_h
#define Morse_h

#include "Arduino.h"
#include "LiquidCrystal_I2C.h"

class ScreenManager
{
  public:
    ScreenManager();
    void display_current_date();
    void display_welcome_message();
  private:
    LiquidCrystal_I2C lcd;
};

#endif

ScreenManager.c

#include "ScreenManager.h"
#include "Arduino.h"
#include "LiquidCrystal_I2C.h"


ScreenManager::ScreenManager()
{
   lcd = LiquidCrystal_I2C(0x27, 16, 2);
}
void ScreenManager::display_current_date(){
    lcd.print("01-09-2015 11:35");
}

void ScreenManager::display_welcome_message()
{
   lcd. print("Hi! What can I do fo you?");
}

编译时出现以下错误:

avr-gcc -Wall -gdwarf-2 -fsigned-char -MD -MP -DF_CPU=8000000 -I arduino -I .. -DARDUINO=105 @arduino/libs.inc -O1 -mmcu=atmega328p  -o "ScreenManager.o" -c "../ScreenManager.cpp"
In file included from ../ScreenManager.cpp:1:
../ScreenManager.h: In constructor 'ScreenManager::ScreenManager()':
../ScreenManager.h:10: error: no matching function for call to 'LiquidCrystal_I2C::LiquidCrystal_I2C()'
../LiquidCrystal_I2C.h:71: note: candidates are: LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t, uint8_t, uint8_t, uint8_t)
../LiquidCrystal_I2C.h:60: note:                 LiquidCrystal_I2C::LiquidCrystal_I2C(const LiquidCrystal_I2C&)
make: *** [ScreenManager.o] Error 1

Error code 2

我做错了什么?

ScreenManager::ScreenManager()
{
   lcd = LiquidCrystal_I2C(0x27, 16, 2);
}

应该是

ScreenManager::ScreenManager() : lcd(0x27, 16, 2 /*, 4th parameter */)
{
}

而ScreenManager.c应该是ScreenManager.cpp

您的私有成员 lcd 调用 LiquidCrystal_I2C class 的默认构造函数。 但是这个class只有一个带参数的构造函数或者一个拷贝构造函数。

所以初始化构造函数初始化列表中的成员。

ScreenManager::ScreenManager() 
: lcd(0x27, 16, 2)
{
}

当你在头文件中声明私有成员变量时,你这样做:

class ScreenManager
{
  public:
    ...
  private:
    LiquidCrystal_I2C lcd;
};

C++ 会在 class 初始化时自动尝试调用 class 的默认构造函数。由于 LiquidCrystal_I2C 未声明默认构造函数,因此当它尝试执行此默认初始化时会抛出您看到的错误。

另一种方法是使用指向 LiquidCrystal_I2C:

指针
class ScreenManager
{
  public:
    ...
  private:
    LiquidCrystal_I2C *lcd;
};

然后在你的构造函数中你用你的参数构造一个 new 对象:

ScreenManager::ScreenManager()
{
   lcd = new LiquidCrystal_I2C(0x27, 16, 2);
}

之后,您只需向 class 添加一个析构函数,这样您的 LiquidCrystal_I2C 对象就会在您完成后得到处理:

// in header
class ScreenManager
{
  public:
    ...
    ~ScreenManager();
    ...
  private:
    LiquidCrystal_I2C lcd;
};

// in source
ScreenManager::~ScreenManager()
{
    delete lcd;
}