#include #include #include #include #include #include #include struct Time {}; template struct DifficultStrategy {}; struct PrintVisitor {}; class Ship { public: Ship& setTime(Time* time) { _time = time; return *this; } Ship& setStrategy(std::unique_ptr> strategy) { _strategy = std::move(strategy); return *this; } Ship& setName(const std::string& name) { _name = name; return *this; } Ship& setCapacity(int capacity) { _capacity = capacity; return *this; } Ship& setMaxCrew(int maxCrew) { _maxCrew = maxCrew; return *this; } Ship& setCrew(int crew) { _crew = crew; return *this; } Ship& setVisitor(std::unique_ptr visitor) { visitor = std::move(_visitor); return *this; } Ship& setArmor(int armor) { _armor = armor; return *this; } Ship& setMaxArmor(int maxArmor) { _maxArmor = maxArmor; return *this; } Ship& setCannons(int cannons) { _canons = cannons; return *this; } Ship& setMaxCannons(int maxCannons) { _maxCannons = maxCannons; return *this; } Ship& setDurability(int durability) { _durability = durability; return *this; } Ship& setMaxDurability(int maxDurability) { _maxDurability = maxDurability; return *this; } const Time* time() const { return _time; } const std::string& name() const { return _name; } int capacity() const { return _capacity; } int maxCrew() const { return _maxCrew; } int crew() const { return _crew; } int armor() const { return _armor; } int maxArmor() const { return _maxArmor; } int canons() const { return _canons; } int maxCannons() const { return _maxCannons; } int durability() const { return _durability; } int maxDurability() const { return _maxDurability; } private: // Allow to be created only by std::unique_ptr friend std::unique_ptr std::make_unique(); Ship() = default; Time* _time{}; std::unique_ptr> _strategy{}; std::string _name{}; int _capacity{-1}; int _maxCrew{-1}; int _crew{10}; std::unique_ptr _visitor{}; int _armor{0}; int _maxArmor{-1}; int _canons{0}; int _maxCannons{-1}; int _durability{100}; int _maxDurability{-1}; }; class ShipBuilder { public: ShipBuilder() : _ship(std::make_unique()) {} [[nodiscard]] std::unique_ptr build() { if (!_ship) { std::cout << "Builder may be use once\n"; return nullptr; } // Check mandatory fields if (!_ship->time() || _ship->name().empty() || _ship->capacity() == -1 || _ship->maxCrew() == -1 || _ship->maxArmor() == -1 || _ship->maxCannons() == -1 || _ship->maxDurability() == -1) { std::cout << "Mandatory fields are not set!\n"; return nullptr; } return std::move(_ship); } ShipBuilder& setTime(Time* time) { _ship->setTime(time); return *this; } ShipBuilder& setStrategy(std::unique_ptr> strategy) { _ship->setStrategy(std::move(strategy)); return *this; } ShipBuilder& setName(const std::string& name) { _ship->setName(name); return *this; } ShipBuilder& setCapacity(int capacity) { _ship->setCapacity(capacity); return *this; } ShipBuilder& setMaxCrew(int maxCrew) { _ship->setMaxCrew(maxCrew); return *this; } ShipBuilder& setCrew(int crew) { _ship->setCrew(crew); return *this; } ShipBuilder& setVisitor(std::unique_ptr visitor) { _ship->setVisitor(std::move(visitor)); return *this; } ShipBuilder& setArmor(int armor) { _ship->setArmor(armor); return *this; } ShipBuilder& setMaxArmor(int maxArmor) { _ship->setMaxArmor(maxArmor); return *this; } ShipBuilder& setCannons(int cannons) { _ship->setCannons(cannons); return *this; } ShipBuilder& setMaxCannons(int maxCannons) { _ship->setMaxCannons(maxCannons); return *this; } ShipBuilder& setDurability(int durability) { _ship->setDurability(durability); return *this; } ShipBuilder& setMaxDurability(int maxDurability) { _ship->setMaxDurability(maxDurability); return *this; } private: std::unique_ptr _ship; }; int main() { auto ship = ShipBuilder().build(); if (ship) { std::cout << "Ship name: " << ship->name() << '\n'; } Time time; auto ship2 = ShipBuilder() .setTime(&time) .setName("Black Pearl") .setCapacity(500) .setMaxCrew(200) .setMaxArmor(1000) .setMaxCannons(20) .setMaxDurability(1000) .build(); if (ship2) { std::cout << "Ship name: " << ship2->name() << '\n'; } }