如何克服存储库模式中的对象切片?

spi*_*kle 0 c++ overriding virtual-functions repository-pattern object-slicing

我有以下代码:

#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();
};
Run Code Online (Sandbox Code Playgroud)

我期望主函数输出相应的猫和狗方法重写函数,但它总是返回“Null”。我相信这是对象切片的情况,并且我不太确定我是否理解为什么 Animal 类构造函数中的引用指针不能避免这个问题。

ste*_*anv 6

切片在这里完成:AnimalRepository repository;。它不能包含子类,因为它是一个实例而不是引用或指针。最简单的方法是将其替换为指向输入副本的唯一智能指针。