在下面的例子中,为什么我不能调用car.getFuelConsumption
class Road {
public:
double length(); // km
int speed(); // km per hour ;
};
class Car {
protected:
virtual double getFuelConsumption(int speed_in_km) = 0;
};
class Tank: public Car{
public:
double getFuelConsumption(int speed_in_km) {
return 1;
}
};
double getPetrol(std::vector<Road> roads, const Car &car) {
double total_fuel_consumption=0;
for (int i=0;i<roads.size();++i)
{
double fuel_consumption_per_road = car.getFuelConsumption(roads[i].speed());
}
return total_fuel_consumption;
}
每辆车都有这样的方法,为什么我不能叫它呢?例如,如果我向getPetrol()
发送一个坦克,那么我希望它能工作并调用坦克版本的getFuelConsumption()
Undefined symbols for architecture x86_64: "Road::speed()", referenced from: getPetrol(std::__1::vector<Road, std::__1::allocator<Road> >, Car const&) in main.cpp.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
代码的明显问题如下:
-
getPetrol()
是在类外部定义的,并且它调用受保护的成员getFuelConsumption()
,则不能在类外部调用受保护的成员。若要修复它,请在基类中
getFuelConsumption()
public
方法。 -
因为你有一个
const
对象参数const Car &car
,方法getFuelConsumption()
需要有const
返回,const
对象不能调用非常量方法。您也可以从car
参数中删除const
关键字,但在这种情况下,第一个选项就足够了。 -
由于您将使用抽象基类对派生类的引用,因此实际上具有多态性,因此还建议使用虚拟析构函数,否则会调用未定义的行为。
-
您提到的链接器错误可能是因为
Road
方法已声明但未定义,至少未在显示的代码中定义。
更正的代码:
现场演示
#include <iostream>
#include <vector>
class Road {
public:
double length(){ return 0;} // added function body to avoid linker error
int speed(){ return 0; } // ""
};
class Car {
public:
virtual double getFuelConsumption(int speed_in_km) const = 0;
virtual ~Car(){} //virtual destructor
};
class Tank : public Car {
public:
double getFuelConsumption(int speed_in_km) const {
return speed_in_km;
}
};
double getPetrol(std::vector<Road> roads, const Car &car) {
double total_fuel_consumption = 0;
for (size_t i = 0; i < roads.size(); ++i) {
total_fuel_consumption += car.getFuelConsumption(roads[i].speed());
}
return total_fuel_consumption;
}
汽车是const
,但方法不是const
。不能对 const 对象调用非 const 方法。请参阅 https://www.learncpp.com/cpp-tutorial/810-const-class-objects-and-member-functions/