std::unordered_map<std::string, std::vector< std::shared_ptr<base_class>>>
class object { public: object(); // , null virtual ~object(); // unique_ptr // object(const object& another); object& operator = (const object& another); // null bool is_null() const; // class data; // const data* get_data() const; // const char* data_class() const; protected: // object(data* new_data); void reset(data* new_data); // void assert_not_null(const char* file, int line) const; private: // std::unique_ptr<data> m_data; };
class object::data { public: // virtual data* clone() const = 0; // virtual const char* class_name() const = 0; };
class asteroid : public object { public: // asteroid(int identifier); // asteroid(const asteroid& another); asteroid& operator = (const asteroid& another); // "" asteroid(const object& another); asteroid& operator = (const object& another); // - int get_identifier() const; // class data; private: // (!) data* m_data; }; class spaceship : public object { public: // spaceship(const char* name); // spaceship(const spaceship& another); spaceship& operator = (const spaceship& another); // "" spaceship(const object& another); spaceship& operator = (const object& another); // " " const char* get_name() const; // class data; private: // (!) data* m_data; };
class asteroid::data : public object::data { public: // data(int identifier); // int get_identifier() const; // ! virtual object::data* clone() const override; // virtual const char* class_name() const override; private: // asteroid int m_identifier; }; class spaceship::data : public object::data { public: // , data(const char* name); // spaceship::data const char* get_name() const; // ! virtual object::data* clone() const override; // virtual const char* class_name() const override; private: // #include <string> std::string m_name; };
object::object() { } object::~object() { } object::object(object::data* new_data) : m_data(new_data) { } object::object(const object& another) : m_data(another.is_null() ? nullptr : another.m_data->clone()) { } object& object::operator = (const object& another) { m_data.reset(another.is_null() ? nullptr : another.m_data->clone()); return *this; } bool object::is_null() const { return !m_data; } const object::data* object::get_data() const { return m_data.get(); } const char* object::data_class() const { return is_null() ? "null" : m_data->class_name(); } void object::reset(object::data* new_data) { m_data.reset(new_data); } void object::assert_not_null(const char* file, int line) const { if (is_null()) { std::stringstream output; output << "Assert 'object is not null' failed at file: '" << file << "' line: " << line; throw std::runtime_error(output.str()); } }
asteroid::asteroid(int identifier) : object(m_data = new asteroid::data(identifier)) { } spaceship::spaceship(const char* name) : object(m_data = new spaceship::data(name)) { }
int asteroid::get_identifier() const { assert_not_null(__FILE__, __LINE__); return m_data->get_identifier(); } const char* spaceship::get_name() const { assert_not_null(__FILE__, __LINE__); return m_data->get_name(); }
asteroid aster(12345); spaceship ship("Alfa-Romeo"); object obj; object obj_aster = asteroid(67890); object obj_ship = spaceship("Omega-Juliette");
Test for null:
aster.is_null (): false
ship.is_null (): false
obj.is_null (): true
obj_aster.is_null (): false
obj_ship.is_null (): false
Test for data class:
aster.data_class (): asteroid
ship.data_class (): spaceship
obj.data_class (): null
obj_aster.data_class (): asteroid
obj_ship.data_class (): spaceship
Test identification:
aster.get_identifier (): 12345
ship.get_name (): Alfa-Romeo
asteroid::asteroid(const asteroid& another) : object(m_data = another.is_null() ? nullptr : static_cast<asteroid::data*>(another.get_data()->clone())) { } asteroid& asteroid::operator = (const asteroid& another) { reset(m_data = another.is_null() ? nullptr : static_cast<asteroid::data*>(another.get_data()->clone())); return *this; } asteroid::asteroid(const object& another) : object(m_data = (dynamic_cast<const asteroid::data*>(another.get_data()) ? dynamic_cast<asteroid::data*>(another.get_data()->clone()) : nullptr)) { } asteroid& asteroid::operator = (const object& another) { reset(m_data = (dynamic_cast<const asteroid::data*>(another.get_data()) ? dynamic_cast<asteroid::data*>(another.get_data()->clone()) : nullptr)); return *this; }
spaceship::spaceship(const spaceship& another) : object(m_data = another.is_null() ? nullptr : static_cast<spaceship::data*>(another.get_data()->clone())) { } spaceship& spaceship::operator = (const spaceship& another) { reset(m_data = another.is_null() ? nullptr : static_cast<spaceship::data*>(another.get_data()->clone())); return *this; } spaceship::spaceship(const object& another) : object(m_data = (dynamic_cast<const spaceship::data*>(another.get_data()) ? dynamic_cast<spaceship::data*>(another.get_data()->clone()) : nullptr)) { } spaceship& spaceship::operator = (const object& another) { reset(m_data = (dynamic_cast<const spaceship::data*>(another.get_data()) ? dynamic_cast<spaceship::data*>(another.get_data()->clone()) : nullptr)); return *this; }
object obj_aster = asteroid(67890); object obj_ship = spaceship("Omega-Juliette"); asteroid aster_obj = obj_aster; spaceship ship_obj = obj_ship;
Test for null:
aster_obj.is_null (): false
ship_obj.is_null (): false
Test for data class:
aster_obj.data_class (): asteroid
ship_obj.data_class (): spaceship
Test identification:
aster_obj.get_identifier (): 67890
ship_obj.get_name (): Omega-Juliette
aster = asteroid(335577); ship = spaceship("Ramambahara"); obj = object(); obj_aster = asteroid(446688); obj_ship = spaceship("Mamburu"); aster_obj = obj_aster; ship_obj = obj_ship;
Test for null:
aster.is_null (): false
ship.is_null (): false
obj.is_null (): true
obj_aster.is_null (): false
obj_ship.is_null (): false
aster_obj.is_null (): false
ship_obj.is_null (): false
Test for data class:
aster.data_class (): asteroid
ship.data_class (): spaceship
obj.data_class (): null
obj_aster.data_class (): asteroid
obj_ship.data_class (): spaceship
aster_obj.data_class (): asteroid
ship_obj.data_class (): spaceship
Test identification:
aster.get_identifier (): 335577
ship.get_name (): Ramambahara
aster_obj.get_identifier (): 446688
ship_obj.get_name (): Mamburu
Source: https://habr.com/ru/post/266999/
All Articles