#include #include #include #include #include #include #include struct Time {}; template struct DifficultStrategy {}; struct PrintVisitor {}; class Ship { public: void setCrew(int crew) { _crew = crew; } void setArmor(int armor) { _armor = armor; } void setCannons(int cannons) { _canons = cannons; } void setDurability(int durability) { _durability = durability; } const std::string& name() const { return _name; } int capacity() const { return _capacity; } int crew() const { return _crew; } int armor() const { return _armor; } int canons() const { return _canons; } int durability() const { return _durability; } private: // Allow to be created only by std::unique_ptr friend std::unique_ptr std::make_unique(); friend class ShipBuilder; 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->_time = time; return *this; } ShipBuilder& setStrategy(std::unique_ptr> strategy) { _ship->_strategy = std::move(strategy); return *this; } ShipBuilder& setName(const std::string& name) { _ship->_name = name; return *this; } ShipBuilder& setCapacity(int capacity) { _ship->_capacity = capacity; return *this; } ShipBuilder& setMaxCrew(int maxCrew) { _ship->_maxCrew = maxCrew; return *this; } ShipBuilder& setCrew(int crew) { _ship->_crew = crew; return *this; } ShipBuilder& setVisitor(std::unique_ptr visitor) { _ship->_visitor = std::move(visitor); return *this; } ShipBuilder& setArmor(int armor) { _ship->_armor = armor; return *this; } ShipBuilder& setMaxArmor(int maxArmor) { _ship->_maxArmor = maxArmor; return *this; } ShipBuilder& setCannons(int cannons) { _ship->_canons = cannons; return *this; } ShipBuilder& setMaxCannons(int maxCannons) { _ship->_maxCannons = maxCannons; return *this; } ShipBuilder& setDurability(int durability) { _ship->_durability = durability; return *this; } ShipBuilder& setMaxDurability(int maxDurability) { _ship->_maxDurability = maxDurability; return *this; } private: std::unique_ptr _ship; }; class ShipJsonBuilder : private ShipBuilder { public: std::unique_ptr buildBrig(Time* time, const std::string& name) { return setTime(time) .setName(name) .setCapacity(500) .setMaxCrew(200) .setMaxArmor(1000) .setMaxCannons(20) .setMaxDurability(1000) .build(); } std::unique_ptr buildFrigate(); std::unique_ptr buildGaleon(); }; 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'; } auto ship3 = ShipJsonBuilder().buildBrig(&time, "Black Widow"); if (ship3) { std::cout << "Ship name: " << ship3->name() << '\n'; } }