#include #include #include #include #include #include #include class AmmunitionVisitor; class Ammunition { public: Ammunition(size_t amount) : _amount(amount) {} virtual ~Ammunition() = default; virtual void accept(const AmmunitionVisitor&) = 0; size_t amount() const { return _amount; } private: size_t _amount = 0; }; class RoundShot; class ChainShot; class GrapeShot; class AmmunitionVisitor { public: virtual ~AmmunitionVisitor() = default; virtual void visit(const RoundShot&) const = 0; virtual void visit(const ChainShot&) const = 0; virtual void visit(const GrapeShot&) const = 0; }; class RoundShot : public Ammunition { public: using Ammunition::Ammunition; void accept(const AmmunitionVisitor& visitor) { visitor.visit(*this); } }; class ChainShot : public Ammunition { public: using Ammunition::Ammunition; void accept(const AmmunitionVisitor& visitor) { visitor.visit(*this); } }; class GrapeShot : public Ammunition { public: using Ammunition::Ammunition; void accept(const AmmunitionVisitor& visitor) { visitor.visit(*this); } }; class DamageVisitor : public AmmunitionVisitor { public: void visit(const RoundShot& shot) const override { std::cout << "Round shot make 20 damages\n"; } void visit(const ChainShot& shot) const override { std::cout << "Chain shot make 30 damages\n"; } void visit(const GrapeShot& shot) const override { std::cout << "Grape shot make 40 damages\n"; } }; class SoundVisitor : public AmmunitionVisitor { public: void visit(const RoundShot& shot) const override { std::cout << "Fiuuuuuuuu Bam!\n"; } void visit(const ChainShot& shot) const override { std::cout << "Fiuuuuuuuuuuu Bam bam!\n"; } void visit(const GrapeShot& shot) const override { std::cout << "Fiuuuuuuuuuuu Bam bam bam bam bam!\n"; } }; int main() { std::unique_ptr grapeShot = std::make_unique(100); SoundVisitor soundVisitor; DamageVisitor damageVisitor; grapeShot->accept(soundVisitor); grapeShot->accept(damageVisitor); }