Reputation: 7681
When I make an Animal
pointer to hold a Duck
object and use a method make_choice
that returns an enum
, it looks as though the method belonging to the base Animal
class is being used instead of the derived Duck
class. How do I instead retain use of the derived classes method?
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
enum Choice{None, Egg, Bone};
class Animal {
protected:
std::string noise = "None";
public:
Animal() = default;
virtual ~Animal() = default;
virtual std::string getNoise() {
return noise;
}
virtual Choice make_choice(){
return None;
}
};
class Duck : public Animal {
public:
Duck() {
noise = "Quack!";
}
Choice make_choice() override {
return Egg;
}
};
int main() {
Duck duck;
cout << duck.make_choice() << endl; // should be 1 for Egg
std::shared_ptr<Animal> duckPtr = std::make_shared<Animal>(duck);
cout << duckPtr->make_choice() << endl; // also should be 1 for Egg, but is 0 for None
return 0;
};
Output:
1 // for Egg
0 // for None
Upvotes: 0
Views: 29
Reputation: 33952
std::make_shared<Animal>(duck);
did not make a Duck
. It made an Animal
by making a copy of duck
and Object Slicing away everything that makes a Duck
different from an Animal
.
You want
std::shared_ptr<Animal> duckPtr = std::make_shared<Duck>(duck);
or just
std::shared_ptr<Animal> duckPtr = std::make_shared<Duck>();
Addressing But what if the pointer later needs to be stored in an array of Animal pointers? from the comments,
std::shared_ptr<Animal> animals[2];
animals[0] = duckPtr;
is perfectly legal. No extra work is required.
Upvotes: 2