I have four .cpp files, Animal, Cattle, Sheep, DrugAdmin.
Animal is parent class of Cattle, and it has calcDose(), which calculates the amount of dose. DrugAdmin is main function.
The thing is, I want to use calcDose() function differently (Cattle, Sheep) and no calcDose() function is needed for Animal class. However, every time I try to use calcDose(), it automatically calls function in Animal class even when I want to use under Cattle class. This is the code I have done so far. (I’ve cut it down)
Animal.cpp
#include "Animal.h"
#include <string>
using namespace std;
Animal::Animal(int newid, double newweight, int yy, int mm, int dd, char newsex, vector<Treatment> treatArray)
{
id = newid;
weight = newweight;
yy = yy;
mm = mm;
dd = dd;
accDose = 0;
sex = newsex;
}
double Animal::calcDose(){
return 0;
}
Cattle.cpp
#include "Cattle.h"
using namespace std;
Cattle::Cattle(int newid, double newweight, int yy, int mm, int dd,
char newsex, vector<Treatment> newtreatArray, string newcategory)
: Animal(newid, newweight, yy,mm,dd, newsex, newtreatArray)
{
id = newid;
weight = newweight;
accDose = 0;
sex = newsex;
Cattle::category = newcategory;
}
Cattle::~Cattle(){}
double Cattle::calcDose(){
if(getDaysDifference() < 90 || getCategory() == "Meat"){
accDose = 0;
return accDose;
}
else if(getCategory() == "Dairy"){
if (weight < 250 || accDose > 200){
accDose = 0;
}
else{
accDose = weight * 0.013 + 46;
}
return accDose;
}
else if(getCategory() == "Breeding"){
if (weight < 250 || accDose > 250){
accDose = 0;
}
else{
accDose = weight * 0.021 + 81;
}
return accDose;
}
else
{
//cout << "It is not valid category" << endl;
}
}
Sheep class is pretty much same but the contents of calcDose()
DrugAdmin.cpp
#include "DrugAdmin.h"
using namespace std;
vector<Animal*> vec_Animal;
void addAnimal(){
int select=0;
int id;
double weight;
int yy;
int mm;
int dd;
char sex;
string category;
vector<Treatment> treatArray;
//user inputs all the values (i've cut it down)
Animal* c1 = new Cattle(id,weight,yy,mm,dd,sex,treatArray,category);
vec_Animal.push_back(c1);
}
void administerDose(int id) //Main Problem
{
vector<Animal*>::iterator ite_Animal = vec_Animal.begin();
for(ite_Animal; ite_Animal != vec_Animal.end(); ++ite_Animal)
cout<<"\nVector contains:"<< (*ite_Animal)->calcDose();
}
I’m sorry for the long and messed up question. Final question is, Cattle has extra data member which is category but the system doesn’t recognise this as well. It recognises as if it is Animal object. Can I have a piece of advice please?
Cheers
Unlike Java (and many other languages), C++ uses what is called “static binding” by default. Static binding means the function called is based on the declared type of the object (or pointer) at compile time, rather than what the object actually is (or what the pointer is actually pointing to).
The alternative to static binding is “dynamic binding”. In dynamic binding, the function called is based on what the object actually is (or what the pointer is actually pointing to) at runtime.
To enable dynamic binding, which is what you’ll want if you have an inheritance hierarchy set up and are maintaining base class pointers (Animal*s), you have to use the keyword
virtual.virtualmakes a function dynamically bound, so that calls to that function will reflect the actual runtime type of the object (Cattle) rather than the compile time declared pointer type (Animal*).To declare a function virtual, you put the virtual keyword before the return value on the function declaration (in the class declaration / .h file):
It is also good style to put virtual on the overridden function in the derived class (calcDose() in Cattle), although the virtual is implied for inherited functions, so putting it there is not strictly necessary.
The one last thing to make sure you to get dynamic binding, is to make sure you always have pointers (or references) to objects rather than objects on the stack (when you want dynamic binding). An object on the stack (i.e. Animal a) can only be it’s declared type, it can’t point to a derived class type. So the
vector<Animal*>you have is perfect, because those pointers can point to Cattle objects (or Animal objects), while a vector could only hold actual animal objects.