创建抽象类并继承时出现MQBIOTExecutor类重定义编译错误求助
嘿,这问题我太熟了——你遇到的是典型的类重复定义编译错误,根源完全出在你错误地把类定义放在.cpp文件里,还让多个源文件直接include这个.cpp。
问题到底出在哪?
C++里,#include本质就是把目标文件的内容原封不动复制到当前文件里。你把MQBIOTExecutor的类定义写在MQBIOTExecutor.cpp里,然后MQBIOT.cpp、MyExecutor.cpp、main.cpp都include了这个.cpp,相当于每个文件里都有一份MQBIOTExecutor的类定义。编译器编译每个.cpp时都没问题,但链接阶段就会发现同一个类被定义了N次,直接报错。
正确的修复步骤
按照C++的工程规范,类的声明/定义要放在**头文件(.h/.hpp)**里,源文件只放实现代码,还要给头文件加保护防止重复包含。
1. 新建MQBIOTExecutor.h头文件
把抽象类的定义移到这个头文件里,加上头文件保护:
#ifndef MQBIOTEXECUTOR_H #define MQBIOTEXECUTOR_H #include <Arduino.h> #include <ArduinoJson.h> class MQBIOTExecutor { public: virtual void getState() = 0; virtual void getCommands() = 0; virtual void executeCommand(JsonDocument jdoc) = 0; virtual void getConfig() = 0; virtual void setConfig(JsonDocument jdoc) = 0; virtual void getSensor() = 0; virtual void extend(String topic, String payload, JsonDocument payloadJsonDoc) = 0; }; #endif // MQBIOTEXECUTOR_H
2. 修改MyExecutor.cpp引用头文件
把原来的#include <MQBIOTExecutor.cpp>改成引用头文件:
#include <Arduino.h> #include <ArduinoJson.h> #include "MQBIOTExecutor.h" // 这里换成头文件,用双引号引用本地头文件 class MyExecutor : public MQBIOTExecutor { public: void getState() override { } // 建议用override替代virtual,更清晰 void getCommands() override { } void executeCommand(JsonDocument jdoc) override { } void getConfig() override { } void setConfig(JsonDocument jdoc) override { } void getSensor() override { } void extend(String topic, String payload, JsonDocument payloadJsonDoc) override { } };
(额外提一句:C++11及以后建议用override关键字标记重写的虚函数,比写virtual更直观,还能帮你检查是不是写错了函数名)
3. 修复其他引用的文件
比如你的MQBIOT.cpp里原来include的是MQBIOTExecutor.cpp,也要改成includeMQBIOTExecutor.h,确保所有需要用这个抽象类的地方都引用头文件,而不是源文件。
为什么之前的尝试没生效?
你说试过把类放入头文件但没解决问题,大概率是没加头文件保护,或者还是不小心include了.cpp文件。头文件保护的作用就是让编译器在第一次include后,后续再遇到相同的include时跳过内容,彻底避免重复定义。
另外,你的抽象类纯虚函数的写法完全没问题,这个错误和纯虚函数半毛钱关系都没有,就是文件包含方式错了~
内容的提问来源于stack exchange,提问作者epileptic

