Reputation: 15
This is kind of a specific question that I had not been able to find a solution to for quite a while. I have this code:
#include <iostream>
using namespace std;
class Mammal
{
public:
Mammal() {cout << "Mammal Constructor\n";}
virtual ~Mammal() {cout << "Mammal Destructor\n";}
virtual void Run() {cout << "Mammal Ran One Space\n";}
protected:
int mammalDistance;
};
class Horse : public Mammal
{
public:
Horse() {cout << "Horse Constructor\n";}
~Horse() {cout << "Horse Destructor\n";}
void Run() {cout << "Horse Ran One Space\n";}
void Run(int distance) {horseDistance = distance;
cout << "Horse Ran " << horseDistance << " Spaces\n";}
protected:
int horseDistance;
};
int main()
{
Mammal *pHorse = new Horse;
pHorse->Run(5);
delete pHorse;
return 0;
}
Now this code works if I take the void Run(int horseDistance) and move it up into Mammal but I wanted to know if there was a way to keep it in horse without it remaining hidden.
Edit: I mean it compiles and works as intended if I take the function that accepts input and move it up into Mammal instead of having it within the Horse class like it is currently. Yes I would like it if it could change the value of horseDistance when it is being passed in. Edit: O I get what your saying. I edited the code.
Upvotes: 0
Views: 171
Reputation: 23265
You have two options. One is to keep track of the fact that your pointer is a horse:
int main()
{
Horse *pHorse = new Horse;
pHorse->Run(5);
delete pHorse;
return 0;
}
The other is to declare a virtual function in Mammal
:
virtual void Run(int mammalDistance) = 0;
I'd pick option #1 if horses were the only things running specific distances, option #2 otherwise.
Upvotes: 1
Reputation: 656
I think you're looking for polymorphism here. All your derived Mammals
simply have to implement getDistance()
and setDistance()
and also can implement getAnimal()
to provide a name. I think there's still some room for improvement on the design, but you'll be getting the hang of polymorphism this way. Something like this perhaps:
#include <iostream>
using namespace std;
class Mammal
{
public:
Mammal() {cout << "Mammal Constructor\n";}
virtual ~Mammal() {cout << "Mammal Destructor\n";}
virtual void Run() {cout << getAnimal() << " Ran " << getDistance() << " Space\n";}
virtual void Run(int p_distance)
{setDistance(p_distance);
cout << getAnimal() << " Ran " << getDistance() << " Spaces\n";}
protected:
virtual void setDistance(int p_distance) {mammalDistance = p_distance;}
virtual int getDistance() {return mammalDistance;}
virtual string getAnimal() {return "Mammal";}
int mammalDistance;
};
class Horse : public Mammal
{
public:
Horse() {cout << "Horse Constructor\n";}
~Horse() {cout << "Horse Destructor\n";}
protected:
int horseDistance;
virtual string getAnimal() {return "Horse";}
};
int main()
{
Mammal *pHorse = new Horse;
pHorse->Run(5);
delete pHorse;
return 0;
}
Upvotes: 0
Reputation: 986
Mammal *pHorse = new Horse;
pHorse->Run(5);
Doesn't work because there is no member function in Mammal with the signature void Run(int)
. More precise: the function void Run(int)
given in the Horse class is not an override for the function void Run()
in Mammal, because of the different signatures.
You should consider adding void Run(int)
to the Mammal interface, if it is a function more subclasses will implement.
Upvotes: 1
Reputation: 1016
Now you know that pHorse is a Horse, but for the compiler, it is different. The only way to do it is to check with dynamic cast if pHorse is a horse and then cast it to a Horse* and cast the method Run(5).
Horse* pHorse2=dynamic_cast<Horse*>(pHorse);
if(pHorse2!=NULL){
pHorse2->Run(5);
}else{
pHorse->Run();
}
Upvotes: 0