I have the following piece of code:
#include <iostream>
class AnimalRepository {
public:
virtual ~AnimalRepository() = default;
virtual auto makeSound() -> void {
std::cout << "Null" << std::endl;
}
};
class CatRepository: public AnimalRepository {
public:
auto makeSound() -> void override {
std::cout << "Meow" << std::endl;
}
};
class DogRepository: public AnimalRepository {
public:
auto makeSound() -> void override {
std::cout << "Woof" << std::endl;
}
};
class Animal {
public:
explicit Animal(const AnimalRepository& repository)
: repository(repository) {
}
auto makeSound() -> void {
return repository.makeSound();
}
protected:
AnimalRepository repository;
};
Animal cat = Animal(CatRepository());
Animal dog = Animal(DogRepository());
int main() {
cat.makeSound();
dog.makeSound();
};
I expected the main function to output the respective cat and dog method override functions, but instead it always returns "Null". I believe this is a case of object slicing, and I'm not quite sure I understand why the reference pointer in the Animal class constructor doesn't avoid this issue.
The slicing is done here: AnimalRepository repository;
. This can't contain a subclass because it is an instance and not a reference or pointer. It is easiest to replace this with a unique smart pointer pointing to a copy of the input.