Error: redefinition of class, despite using include guards
Error: redefinition of class, despite using include guards
我是一名 javascript/typescript 开发人员,但我是 Arduino/c++
的新手
我有一个 class(见下面的 h 和 cpp)并且有这个编译器错误:
DotMatrix.cpp:13:1: error: redefinition of 'DotMatrix::DotMatrix(uint8_t, MD_MAX72XX::moduleType_t, uint8_t, uint8_t, uint8_t)'
DotMatrix::DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
^
In file included from sketch/DotMatrix.cpp:5:0:
DotMatix.h:10:3: error: 'DotMatrix::DotMatrix(uint8_t, MD_MAX72XX::moduleType_t, uint8_t, uint8_t, uint8_t)' previously defined here
DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
^
exit status 1
我不明白为什么...
文件如下:
DotMatix.h:
#ifndef DotMatrix_h
#define DotMatrix_h
#include <MD_MAX72xx.h>
#include <MD_Parola.h>
class DotMatrix
{
public:
DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
: _parola(hardwareType, csPin, maxDevices)
{};
void setup();
private:
MD_Parola _parola;
};
#endif
DotMatix.cpp:
#ifndef DotMatrix_cpp
#define DotMatrix_cpp
//#include <stdint.h>
#include "DotMatix.h"
#include "Arduino.h"
#include <MD_Parola.h> // Parola library to scroll and display text on the display (needs MD_MAX72xx library) https://github.com/MajicDesigns/MD_Parola
#include <MD_MAX72xx.h> // Library to control the Maxim MAX7219 chip on the dot matrix module https://github.com/MajicDesigns/MD_MAX72XX
const int FRAME_DELAY = 25;
DotMatrix::DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
: _parola(hardwareType, csPin, maxDevices)
{
//MD_Parola(MD_MAX72XX::moduleType_t mod, uint8_t csPin, uint8_t numDevices = (uint8_t)'[=12=]1')
_parola = MD_Parola(hardwareType, csPin, maxDevices);
}
void DotMatrix::setup()
{
this->_parola.begin();
_parola.displayClear();
_parola.displaySuspend(false);
byte i = 3; //EEPROM.read(0);
_parola.setIntensity(i); // Values from 0 to 15
_parola.setTextEffect(PA_SCROLL_LEFT, PA_SCROLL_LEFT); //in and out effect
_parola.displayScroll("Hallokes ...", PA_LEFT, PA_SCROLL_LEFT, FRAME_DELAY);
}
#endif
作为参考,这是调用 class:
的 ino 文件的(片段)
#include "DotMatix.h"
// Define the number of 8x8 dot matrix devices and the hardware SPI interface
#define MAX_DEVICES 4
#define HARDWARE_TYPE MD_MAX72XX::DR1CR0RR0_HW
#define CLK_PIN 14 //D5
#define DATA_PIN 13 //D7
#define CS_PIN 2 //D4
DotMatrix dotMatrix(MAX_DEVICES, HARDWARE_TYPE, CLK_PIN, DATA_PIN, CS_PIN);
void setup() {
dotMatrix.setup();
}
void loop() {
}
我正在使用 VS Code IDE 和 Arduino 扩展。
您应更改 DotMatrix.h 的这一行:
DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
: _parola(hardwareType, csPin, maxDevices)
{};
应该是:
DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
: _parola(hardwareType, csPin, maxDevices);
如果不是,您将直接在头文件中实现构造函数(构造函数什么都不做)。实施为“{}”(无事可做)
然后当编译器在 .cpp 文件中看到另一个实现(正确的)时,它说它已经被定义了。
void func(); // function declaration
void func() { blablabla; } // function definition.
您可能会看到定义和声明之间的简单区别。一个有{
,一个没有。一个(全局)函数在代码库中可能只定义一次,而不是两次。否则你的编译器将不知道选择哪个函数——第一个?第二个?
你做到了:
// in DotMatix.h:
DotMatrix(blablaa)
{}; // yes this is definition
也做了:
// in DotMatrix.cpp
DotMatrix::DotMatrix(ublabla, who cares)
{ // also definition
编译器发现同一函数的两个定义并退出并出错。
包含防护通常用于防止包含同一个文件两次。您的多个定义在多个文件中。也不需要在源文件中包含 guard - 源文件并不意味着包含,因此它们将始终被处理一次。
您定义了两次构造函数。 DotMatrix
的第一个定义在 header DotMatix.h
:
中的 class 定义本身内
class DotMatrix
{
public:
DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
: _parola(hardwareType, csPin, maxDevices)
{};
//...
注意构造函数定义后的空语句;
是多余的
这个定义定义了一个内联函数。
注意构造函数有未使用的参数。
构造函数的第二个定义DotMatrix
在模块DotMatix.cpp
:
中
DotMatrix::DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
: _parola(hardwareType, csPin, maxDevices)
{
//MD_Parola(MD_MAX72XX::moduleType_t mod, uint8_t csPin, uint8_t numDevices = (uint8_t)'[=11=]1')
_parola = MD_Parola(hardwareType, csPin, maxDevices);
}
此外,此定义在构造函数的 body 中包含数据成员 _parola
的冗余赋值。
完全删除模块 DotMatix.cpp
.
中构造函数的定义
还有这些守卫指令
#ifndef DotMatrix_cpp
#define DotMatrix_cpp
没有多大意义,因为模块并非设计为包含在其他模块中。
感谢所有的输入!
我已经删除了 cpp 文件中的构造函数,现在一切正常。
另外,cpp 文件中的 include guard 确实是一件愚蠢的事情!
来自 js / typescript,整个头文件和奇怪的 initialiser list 语法仍在我脑海中创建快捷方式 ;-)
关于初始化列表:这是用带参数的构造函数声明 class 变量的唯一方法吗?这对我来说太奇怪了......
我是一名 javascript/typescript 开发人员,但我是 Arduino/c++
的新手我有一个 class(见下面的 h 和 cpp)并且有这个编译器错误:
DotMatrix.cpp:13:1: error: redefinition of 'DotMatrix::DotMatrix(uint8_t, MD_MAX72XX::moduleType_t, uint8_t, uint8_t, uint8_t)'
DotMatrix::DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
^
In file included from sketch/DotMatrix.cpp:5:0:
DotMatix.h:10:3: error: 'DotMatrix::DotMatrix(uint8_t, MD_MAX72XX::moduleType_t, uint8_t, uint8_t, uint8_t)' previously defined here
DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
^
exit status 1
我不明白为什么...
文件如下:
DotMatix.h:
#ifndef DotMatrix_h
#define DotMatrix_h
#include <MD_MAX72xx.h>
#include <MD_Parola.h>
class DotMatrix
{
public:
DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
: _parola(hardwareType, csPin, maxDevices)
{};
void setup();
private:
MD_Parola _parola;
};
#endif
DotMatix.cpp:
#ifndef DotMatrix_cpp
#define DotMatrix_cpp
//#include <stdint.h>
#include "DotMatix.h"
#include "Arduino.h"
#include <MD_Parola.h> // Parola library to scroll and display text on the display (needs MD_MAX72xx library) https://github.com/MajicDesigns/MD_Parola
#include <MD_MAX72xx.h> // Library to control the Maxim MAX7219 chip on the dot matrix module https://github.com/MajicDesigns/MD_MAX72XX
const int FRAME_DELAY = 25;
DotMatrix::DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
: _parola(hardwareType, csPin, maxDevices)
{
//MD_Parola(MD_MAX72XX::moduleType_t mod, uint8_t csPin, uint8_t numDevices = (uint8_t)'[=12=]1')
_parola = MD_Parola(hardwareType, csPin, maxDevices);
}
void DotMatrix::setup()
{
this->_parola.begin();
_parola.displayClear();
_parola.displaySuspend(false);
byte i = 3; //EEPROM.read(0);
_parola.setIntensity(i); // Values from 0 to 15
_parola.setTextEffect(PA_SCROLL_LEFT, PA_SCROLL_LEFT); //in and out effect
_parola.displayScroll("Hallokes ...", PA_LEFT, PA_SCROLL_LEFT, FRAME_DELAY);
}
#endif
作为参考,这是调用 class:
的 ino 文件的(片段)#include "DotMatix.h"
// Define the number of 8x8 dot matrix devices and the hardware SPI interface
#define MAX_DEVICES 4
#define HARDWARE_TYPE MD_MAX72XX::DR1CR0RR0_HW
#define CLK_PIN 14 //D5
#define DATA_PIN 13 //D7
#define CS_PIN 2 //D4
DotMatrix dotMatrix(MAX_DEVICES, HARDWARE_TYPE, CLK_PIN, DATA_PIN, CS_PIN);
void setup() {
dotMatrix.setup();
}
void loop() {
}
我正在使用 VS Code IDE 和 Arduino 扩展。
您应更改 DotMatrix.h 的这一行:
DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
: _parola(hardwareType, csPin, maxDevices)
{};
应该是:
DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
: _parola(hardwareType, csPin, maxDevices);
如果不是,您将直接在头文件中实现构造函数(构造函数什么都不做)。实施为“{}”(无事可做) 然后当编译器在 .cpp 文件中看到另一个实现(正确的)时,它说它已经被定义了。
void func(); // function declaration
void func() { blablabla; } // function definition.
您可能会看到定义和声明之间的简单区别。一个有{
,一个没有。一个(全局)函数在代码库中可能只定义一次,而不是两次。否则你的编译器将不知道选择哪个函数——第一个?第二个?
你做到了:
// in DotMatix.h:
DotMatrix(blablaa)
{}; // yes this is definition
也做了:
// in DotMatrix.cpp
DotMatrix::DotMatrix(ublabla, who cares)
{ // also definition
编译器发现同一函数的两个定义并退出并出错。
包含防护通常用于防止包含同一个文件两次。您的多个定义在多个文件中。也不需要在源文件中包含 guard - 源文件并不意味着包含,因此它们将始终被处理一次。
您定义了两次构造函数。 DotMatrix
的第一个定义在 header DotMatix.h
:
class DotMatrix
{
public:
DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
: _parola(hardwareType, csPin, maxDevices)
{};
//...
注意构造函数定义后的空语句;
是多余的
这个定义定义了一个内联函数。
注意构造函数有未使用的参数。
构造函数的第二个定义DotMatrix
在模块DotMatix.cpp
:
DotMatrix::DotMatrix(uint8_t maxDevices, MD_MAX72XX::moduleType_t hardwareType, uint8_t clkPin, uint8_t dataPin, uint8_t csPin)
: _parola(hardwareType, csPin, maxDevices)
{
//MD_Parola(MD_MAX72XX::moduleType_t mod, uint8_t csPin, uint8_t numDevices = (uint8_t)'[=11=]1')
_parola = MD_Parola(hardwareType, csPin, maxDevices);
}
此外,此定义在构造函数的 body 中包含数据成员 _parola
的冗余赋值。
完全删除模块 DotMatix.cpp
.
还有这些守卫指令
#ifndef DotMatrix_cpp
#define DotMatrix_cpp
没有多大意义,因为模块并非设计为包含在其他模块中。
感谢所有的输入! 我已经删除了 cpp 文件中的构造函数,现在一切正常。 另外,cpp 文件中的 include guard 确实是一件愚蠢的事情!
来自 js / typescript,整个头文件和奇怪的 initialiser list 语法仍在我脑海中创建快捷方式 ;-)
关于初始化列表:这是用带参数的构造函数声明 class 变量的唯一方法吗?这对我来说太奇怪了......