C++多继承场景报'Vehicle':base class undefined错误排查
问题根因
报'Vehicle':base class undefined以及后续连锁编译错误,核心是三类低级写法错误:
- 派生类头文件声明继承
Vehicle时,没有提前引入Vehicle.h,编译器看不到Vehicle的类定义,自然无法识别基类 - 错误在多个头文件、cpp文件中
#include了.cpp实现文件:C++中.cpp是独立编译单元,永远不要被其他文件include,否则必然触发重复定义链接错误 - 文件名和引用名不匹配:汽油车类头文件命名为
Gasoline.h,但其他代码中引用的是GasolineVehicle.h - 多层继承时上层头文件缺依赖:
HybridVehicle.h使用了ElectricVehicle和GasolineVehicle类,但没有引入两个父类的头文件
修复步骤
1. 统一修正所有头文件,只include依赖的头文件、不碰cpp
ElectricVehicle.h
新增基类头文件引用,修正后代码:
#pragma once #ifndef ElectricVehicle_h #define ElectricVehicle_h #include <iostream> #include "Vehicle.h" // 必须引入,否则编译器不知道Vehicle是什么 class ElectricVehicle : virtual public Vehicle { public: float maximumCharge; float currentCharge; float engineEfficiency; public: ElectricVehicle(float max, float eff); float calculateRange(); float percentEnergyRemaining(); void drive(float km); ~ElectricVehicle(); }; #endif
GasolineVehicle.h
先把原文件名Gasoline.h重命名为GasolineVehicle.h,和其他文件的引用名保持一致,再新增基类头文件引用:
#pragma once #include <iostream> #include "Vehicle.h" // 必须引入基类定义 #ifndef GasolineVehicle_h #define GasolineVehicle_h class GasolineVehicle : virtual public Vehicle { public: float maximumGasoline; float currentGasoline; float engineEfficiency; GasolineVehicle(float max, float eff); ~GasolineVehicle(); float calculateRange(); float percentEnergyRemaining(); void drive(float km); }; #endif
HybridVehicle.h
新增两个直接父类的头文件引用:
#pragma once #ifndef HybridVehicle_h #define HybridVehicle_h #include "ElectricVehicle.h" #include "GasolineVehicle.h" class HybridVehicle: public GasolineVehicle, public ElectricVehicle { public: HybridVehicle(float gMax, float gEff, float eMax, float eEff); ~HybridVehicle(); float calculateRange(); float percentEnergyRemaining(); void drive(float km); }; #endif
2. 修正所有cpp文件,删除所有对.cpp的引用,只include对应头文件
所有cpp文件去掉无意义的#pragma once(该宏仅用于头文件防重复包含,cpp不需要):
Vehicle.cpp
#include "Vehicle.h" #include <iostream> using namespace std; Vehicle::~Vehicle() { cout << "In vehicle destructor" << endl; }
ElectricVehicle.cpp
#include "Vehicle.h" #include "ElectricVehicle.h" #include <iostream> using namespace std; ElectricVehicle::ElectricVehicle(float maxEnergy, float rating) { engineEfficiency = rating; maximumCharge = maxEnergy; currentCharge = maxEnergy; } ElectricVehicle::~ElectricVehicle() { cout << "In Electric vehicle destructor" << endl; } float ElectricVehicle::calculateRange() { return (currentCharge * 100 / engineEfficiency); } float ElectricVehicle::percentEnergyRemaining() { return (currentCharge * 100.0f / maximumCharge); } void ElectricVehicle::drive(float km) { if (currentCharge < 0) { cout << "Your Car is out of energy"; return; } currentCharge -= (km / 100) * engineEfficiency; }
GasolineVehicle.cpp
#include "Vehicle.h" #include "GasolineVehicle.h" #include <iostream> using namespace std; GasolineVehicle::GasolineVehicle(float maxEnergy, float rating) { engineEfficiency = rating; maximumGasoline = maxEnergy; currentGasoline = maxEnergy; } GasolineVehicle::~GasolineVehicle() { cout << "In Gasoline vehicle destructor" << endl; } float GasolineVehicle::calculateRange() { return currentGasoline * 100 / engineEfficiency; } float GasolineVehicle::percentEnergyRemaining() { return (currentGasoline * 100.0f / maximumGasoline); } void GasolineVehicle::drive(float km) { if (currentGasoline < 0){ cout << "Your Car is out of energy"; return; } currentGasoline -= (km / 100) * engineEfficiency; }
HybridVehicle.cpp
#include "HybridVehicle.h" #include <iostream> using namespace std; HybridVehicle::HybridVehicle(float maxGasoline, float gasefficiency, float maxcharge, float electricefficiency) :GasolineVehicle(maxGasoline, gasefficiency), ElectricVehicle(maxcharge, electricefficiency) {} HybridVehicle::~HybridVehicle() { cout << "In Hybrid vehicle destructor" << endl; } float HybridVehicle::calculateRange() { return (currentCharge / ElectricVehicle::engineEfficiency) * 100 + (currentGasoline / GasolineVehicle::engineEfficiency) * 100; } float HybridVehicle::percentEnergyRemaining() { return ((currentCharge + currentGasoline) / (maximumCharge + maximumGasoline)) * 100.0f; } void HybridVehicle::drive(float km) { if (currentGasoline + currentCharge < 0) { cout << "Your Car is out of energy"; return; } else if (currentCharge > 0) { currentCharge -= (km / 100) * ElectricVehicle::engineEfficiency; } else { currentGasoline -= (km / 100) * GasolineVehicle::engineEfficiency; } }
入口文件Week2.cpp
修正错误的类型强转,去掉对cpp的引用:
#include "Vehicle.h" #include "ElectricVehicle.h" #include "GasolineVehicle.h" #include "HybridVehicle.h" #include <iostream> using namespace std; Vehicle* testVehicle(Vehicle* pVehicle, const char* vehicleName) { cout << vehicleName << " s range is: " << pVehicle->calculateRange() << endl; pVehicle->drive(150); cout << vehicleName << " s energy left is: " << pVehicle->percentEnergyRemaining() << endl; cout << vehicleName << " s range is now: " << pVehicle->calculateRange() << endl; return pVehicle; } int main(int argc, char** argv) { //50L of gas, 7.1 L/100km delete testVehicle(new GasolineVehicle(50, 7.1), "Corolla"); //42 L of gas, 4.3 L/100km, 8.8kWh, 22 kWh/100km delete testVehicle((Vehicle*)new HybridVehicle(42, 4.3, 8.8, 22.0), "Prius"); // 原代码强转为GasolineVehicle*不符合多态逻辑,改为基类Vehicle* //75 kWh, 16 kWh/100km delete testVehicle(new ElectricVehicle(75, 16), "Tesla 3"); return 0; }
编译注意事项
编译时需要把所有cpp文件加入编译列表,不要只编译Week2.cpp,要将Vehicle.cpp/ElectricVehicle.cpp/GasolineVehicle.cpp/HybridVehicle.cpp/Week2.cpp统一编译链接即可正常运行。
内容的提问来源于stack exchange,提问作者Alice Smith
相关产品推荐
相关产品推荐

