Reputation:
In the following example, why I can't call 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;
}
Every car has such a method so why I can't call it? For Example if I send a Tank to getPetrol()
then I expect it to work and call Tank's version of 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)
Upvotes: 0
Views: 101
Reputation: 23832
The visible issues with your code are the following:
getPetrol()
is defined outside the class and it calls a protected member getFuelConsumption()
, protected members can't be called outside the class.
To fix it you make getFuelConsumption()
a public
method in the base class.
Because you have a const
object argument const Car &car
, the method getFuelConsumption()
needs to have const
return, const
objects can't call non-const methods. You could also remove const
keyword from the car
argument, but the first option is adequate in this case.
As you are going to use references of the abstract base class to derived classes, effectively polymorphism, the use of a virtual destructor is also advised, under penalty of invoking undefined behavior.
The linker error you mention can be because Road
methods are declared but not defined, at least not in the code you show.
Corrected code:
#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;
}
Upvotes: 1
Reputation: 16952
car is const
, but the method is not const
. You cannot call a non-const method on a const object. See https://www.learncpp.com/cpp-tutorial/810-const-class-objects-and-member-functions/
Upvotes: 0