Arduino/C++类重定义错误求助:已用包含保护仍报错
解决DotMatrix构造函数重定义错误的方案
作为从JS/TS转Arduino/C的开发者,这种重定义错误其实是C类定义的常见坑,我帮你拆解问题并给出修复步骤:
核心问题分析
你遇到的redefinition错误,本质是同一个构造函数被定义了两次:
DotMatrix.cpp:13:1: error: redefinition of 'DotMatrix::DotMatrix(...)'
DotMatix.h:10:3: error: 'DotMatrix::DotMatrix(...)' previously defined here
在你的头文件DotMatix.h中,构造函数已经通过{}完成了类内实现:
DotMatrix(...) : _parola(...) {}; // 这里的{}已经是空实现,属于类内定义
而在DotMatix.cpp中,你又重新写了一遍构造函数的实现,这就触发了C++的重定义规则——类内定义的函数默认是inline,后续再定义会被视为重复。
另外还有两个次要问题:
- 文件名拼写不一致:
DotMatix.h少了一个字母r(应该是DotMatrix.h),虽然当前编译能找到,但容易引发后续路径问题 .cpp文件不需要包含保护(#ifndef DotMatrix_cpp),这是头文件用来防止重复包含的机制,cpp文件单独编译,用了反而可能出问题- 构造函数体内重复初始化
_parola:初始化列表已经完成了对象构造,没必要再赋值一次
修复步骤
1. 修正头文件(DotMatrix.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); void setup(); private: MD_Parola _parola; }; #endif
2. 修正cpp文件(DotMatrix.cpp)
去掉多余的包含保护,删除构造函数体内重复的赋值语句:
#include "DotMatrix.h" #include "Arduino.h" #include <MD_Parola.h> #include <MD_MAX72xx.h> 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) { // 这里不需要再写_parola = MD_Parola(...),初始化列表已经完成构造 } void DotMatrix::setup() { this->_parola.begin(); _parola.displayClear(); _parola.displaySuspend(false); byte i = 3; _parola.setIntensity(i); _parola.setTextEffect(PA_SCROLL_LEFT, PA_SCROLL_LEFT); _parola.displayScroll("Hallokes ...", PA_LEFT, PA_SCROLL_LEFT, FRAME_DELAY); }
3. 修正ino文件的头引用
把#include "DotMatix.h"改成#include "DotMatrix.h",保证文件名一致:
#include "DotMatrix.h" #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() { }
关键知识点补充
在C++中:
- 类内带
{}的函数会被视为inline函数,编译器会尝试将其嵌入调用处 - 如果同一个函数在类内和cpp文件中分别定义,就会触发重定义错误
- 头文件的包含保护是为了防止多次包含导致类重复声明,cpp文件不需要这个机制
内容的提问来源于stack exchange,提问作者user2375613
相关产品推荐
相关产品推荐

