128 lines
3.1 KiB
C++
128 lines
3.1 KiB
C++
#include <algorithm>
|
|
#include <cassert>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <memory>
|
|
#include <set>
|
|
#include <variant>
|
|
#include <vector>
|
|
|
|
class AbstractVisitor;
|
|
|
|
class Ammunition {
|
|
public:
|
|
Ammunition(size_t amount)
|
|
: _amount(amount) {}
|
|
virtual ~Ammunition() = default;
|
|
|
|
virtual void accept(const AbstractVisitor&) = 0;
|
|
|
|
size_t amount() const { return _amount; }
|
|
|
|
private:
|
|
size_t _amount = 0;
|
|
};
|
|
|
|
class RoundShot;
|
|
class ChainShot;
|
|
class GrapeShot;
|
|
|
|
class AbstractVisitor {
|
|
protected:
|
|
// Can be only use by derived class
|
|
virtual ~AbstractVisitor() = default;
|
|
};
|
|
|
|
class RoundShotVisitor {
|
|
public:
|
|
virtual void visit(const RoundShot& shot) const = 0;
|
|
|
|
protected:
|
|
virtual ~RoundShotVisitor() = default;
|
|
};
|
|
|
|
class GrapeShotVisitor {
|
|
public:
|
|
virtual void visit(const GrapeShot& shot) const = 0;
|
|
|
|
protected:
|
|
virtual ~GrapeShotVisitor() = default;
|
|
};
|
|
|
|
class ChainShotVisitor {
|
|
public:
|
|
virtual void visit(const ChainShot& shot) const = 0;
|
|
|
|
protected:
|
|
virtual ~ChainShotVisitor() = default;
|
|
};
|
|
|
|
class DamageVisitor : public AbstractVisitor,
|
|
public RoundShotVisitor,
|
|
public GrapeShotVisitor,
|
|
public ChainShotVisitor {
|
|
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 AbstractVisitor,
|
|
public RoundShotVisitor,
|
|
public GrapeShotVisitor,
|
|
public ChainShotVisitor {
|
|
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";
|
|
}
|
|
};
|
|
|
|
class RoundShot : public Ammunition {
|
|
public:
|
|
using Ammunition::Ammunition;
|
|
void accept(const AbstractVisitor& visitor) {
|
|
if (const auto* v = dynamic_cast<const RoundShotVisitor*>(&visitor)) {
|
|
v->visit(*this);
|
|
}
|
|
}
|
|
};
|
|
|
|
class ChainShot : public Ammunition {
|
|
public:
|
|
using Ammunition::Ammunition;
|
|
void accept(const AbstractVisitor& visitor) {
|
|
if (const auto* v = dynamic_cast<const ChainShotVisitor*>(&visitor)) {
|
|
v->visit(*this);
|
|
}
|
|
}
|
|
};
|
|
|
|
class GrapeShot : public Ammunition {
|
|
public:
|
|
using Ammunition::Ammunition;
|
|
void accept(const AbstractVisitor& visitor) {
|
|
if (const auto* v = dynamic_cast<const GrapeShotVisitor*>(&visitor)) {
|
|
v->visit(*this);
|
|
}
|
|
}
|
|
};
|
|
|
|
int main() {
|
|
std::unique_ptr<Ammunition> grapeShot = std::make_unique<GrapeShot>(100);
|
|
SoundVisitor soundVisitor;
|
|
DamageVisitor damageVisitor;
|
|
grapeShot->accept(soundVisitor);
|
|
grapeShot->accept(damageVisitor);
|
|
}
|