
ããã¯äœã®ããã§ããïŒ
ååãšããŠãé«éãªãã®ã¯C ++ã§èšè¿°ãããŠããŸãããåžžã«äœ¿ãããããšã¯éããŸããã 補åã®éçºããã»ã¹ã§ã¯ã補åãšã³ãã£ãã£ãæäœããããã®éåžžã«äžååã«èšèšãããã€ã³ã¿ãŒãã§ã€ã¹ãæã€äžè¬çãªæ©èœã匷調衚瀺ãããŸãã C ++èšèªã¯ãã³ãŒããä¹ç®ããââã³è€éåããããããçš®é¡ã®ãã¹ããŒãããã€ã³ã¿ãŒã§ã©ãããããã®ãããªæ§é ã«ã¢ã¯ã»ã¹ããããã®ããã¡ãŒãã«ç·ãçæããåºæ¬ã¯ã©ã¹ãžã®ãã€ã³ã¿ãŒãšãªã³ã¯ã匷ãæšå¥šããŸãã
åæããŠãããã䜿çšããããšã¯ã»ãšãã©äŸ¿å©ã§ã¯ãããŸããïŒ
std::unordered_map<std::string, std::vector< std::shared_ptr<base_class>>>
ç¹ã«ããã¯ã¿ãŒã®åèŠçŽ ã«å¯ŸããŠåŸç¶ã¯ã©ã¹ã®æäœãå¿ èŠãªå Žåãã€ãŸããã¡ãœããã¯äžèšã®base_classã«å«ãŸããŸããã ã³ã³ã¹ãã©ã¯ãã§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; };
以åã«åºæ¬ã¯ã©ã¹ãžã®ã€ã³ã¿ãŒãã§ã€ã¹ãšããŠäœ¿çšããŠãããã®ã¯ããªããžã§ã¯ã::ããŒã¿ã«å€ãããŸã-ããã¯ãä»ã®ã©ãã«ã衚瀺ãããªãæãéèŠãªã¯ã©ã¹ã§ãã
å®éãobjectããã³object :: dataã«ã¯ãbase_classãèšå®ãããåºæ¬æäœãååšããå¿ èŠããããŸãã ãããã説æã§ã¯ãããã¯å¿ èŠãããŸããããããªãã§ã¯ãå€ãã®èå³æ·±ãããšããããŸãã
æå°éã®åœ¢åŒã§ã¯ããªããžã§ã¯ãã®ããŒã¿ã¯ã©ã¹ã¯ã©ãã«ãåçŽã§ã¯ãããŸããã
class object::data { public: // virtual data* clone() const = 0; // virtual const char* class_name() const = 0; };
åºæ¬ã¯ã©ã¹ã§æ¬åœã«å¿ èŠãªå¯äžã®ã¡ãœããã¯ã察å¿ããçžç¶äººã®ããŒã¿ãè€è£œããããšã§ãã ããã«ãã芧ã®ãšãããã€ã³ã¿ãŒãã§ã€ã¹ã¯ã©ã¹ã¯cloneïŒïŒã¡ãœããããªããŠãåé¡ãããŸããããªããžã§ã¯ãèªäœãšãã®ãã¹ãŠã®åå«ã¯éåžžã®ã³ããŒã³ã³ã¹ãã©ã¯ã¿ãŒã䜿çšããŸãã ããã§ãæãéèŠãªããšã«æ³šç®ããŸã-ã«ãã»ã«åãããåºæ¬ã¯ã©ã¹ããã®ç¶æ¿ã§ãã
äºéç¶æ¿
çžç¶äººã®ããã«ããšã³ãã£ãã£ã®ãã¢ãéžæããå¿ èŠããããŸãã å®å®è¹ãšå°ææãæã€ã³ã³ãã¥ãŒã¿ãŒã²ãŒã ãéçºããŸãããã ãããã£ãŠãåäœããã«ã¯2çµã®ã¯ã©ã¹ãå¿ èŠã§ããå°ææãšå®å®è¹ã§ãã
çžç¶äººããŠããŒã¯ãªæ¹æ³ã§ã¯ã©ã¹ã«è¿œå ããŸãããïŒå°ææã¯æŽæ°èå¥åã§ç°ãªããå®å®è¹ã¯ãŠããŒã¯ãªååã§èå¥ãããŸãïŒ
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; };
次ã«ãå®è£ ã«ã€ããŠããå°ã説æããŸãããã¹ãŠãããã«å®è¡ãããŸãã
ã¡ãœããã®å®è£
ããã©ã«ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã«ãã£ãŠãªããžã§ã¯ãåã®ã€ã³ã¹ã¿ã³ã¹ãçŽæ¥äœæãããšãnullå€ãæã€ãªããžã§ã¯ããäœæãããŸãã
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)) { }
ãããã®æ°è¡ãããããããã«ããã§ãŒãºãã©ã¹ã¿ãŒã®1ã€ã®ã²ãšå£ã§ãããŠãµã®ã®çŸ€ãã ããããã«æ®ºããŸãã
- éåžžã®ã³ã³ã¹ãã©ã¯ã¿ãŒã«ããç¹å¥ãªã³ã³ãããŒã¯ã©ã¹ã®ããŒã¿ãžã®åç §ã䜿çšããŠãçžç¶äººãäœæããŸãã
- ã³ã³ããã¯ã©ã¹ã¯ä»ã®ãã¹ãŠã®åºåºã¯ã©ã¹ã§ããããã€ã³ã¿ãŒãã§ã€ã¹ãæ ŒçŽãããã¹ãŠã®åºæ¬çãªäœæ¥ã¯åºåºã¯ã©ã¹ã§è¡ãããŸãã
- äžäœã¯ã©ã¹ã«ã¯ãm_dataã®å¯Ÿå¿ããã¯ã©ã¹ã®ããŒã¿ã¯ã©ã¹ãæäœããããã®ã€ã³ã¿ãŒãã§ã€ã¹ããããŸãã
- åç §ã§ã¯ãªããæãäžè¬çãªã¯ã©ã¹ã䜿çšããŠãã¯ã©ã¹ã€ã³ã¹ã¿ã³ã¹ãæäœããããã®C ++èªååã®ãã¹ãŠã®å©ç¹ãååŸããŸãã
ãã¡ãããããŒã¿ã«ã¢ã¯ã»ã¹ãããšãã察å¿ããã¯ã©ã¹ã¯ç¬èªã®åå«ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããããŒã¿ã®nullããã§ãã¯ããŸãã
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");
ç§ãã¡ã¯ãã§ãã¯ããŸãïŒ
nullã®ãã¹ãïŒ
aster.is_nullïŒïŒïŒfalse
ship.is_nullïŒïŒïŒfalse
obj.is_nullïŒïŒïŒtrue
obj_aster.is_nullïŒïŒïŒfalse
obj_ship.is_nullïŒïŒïŒfalse
ããŒã¿ã¯ã©ã¹ã®ãã¹ãïŒ
aster.data_classïŒïŒïŒå°ææ
ship.data_classïŒïŒïŒå®å®è¹
obj.data_classïŒïŒïŒnull
obj_aster.data_classïŒïŒïŒå°ææ
obj_ship.data_classïŒïŒïŒå®å®è¹
ãã¹ãèå¥ïŒ
aster.get_identifierïŒïŒïŒ12345
ship.get_nameïŒïŒïŒã¢ã«ãã¡ãã¡ãª
CïŒãJavaãPythonãªã©ã®é«æ°Žæºèšèªã«äŒŒãŠããŸãããïŒ å¯äžã®é£ããã¯ããªããžã§ã¯ãã«è©°ã蟌ãŸããçžç¶äººã®ã€ã³ã¿ãŒãã§ãŒã¹ãåãæ»ãããšã§ãã 次ã«ã以åã«ãªããžã§ã¯ãã«ããã¯ãããŠãããã®ãå°ææãå®å®è¹ã®ã€ã³ã¹ã¿ã³ã¹ã«æœåºããæ¹æ³ãåŠã³ãŸãã
ãŠã§ã€ã¢ãã
å¿ èŠãªã®ã¯ãåæåèªäœã¯ããŸãããŸããããŸãããã掟çã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒããªãŒããŒããŒãããããšã§ãã
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; }
ã芧ã®ãšãããããã§ã¯dynamic_castã䜿çšããå¿ èŠããããŸããããŒã¿ã¯ã©ã¹ã®éå±€ãäžã«ç§»åããå¿ èŠãããããã§ãã ããã¯å·šå€§ã«èŠããŸãããçµæã¯äŸ¡å€ããããŸãïŒ
object obj_aster = asteroid(67890); object obj_ship = spaceship("Omega-Juliette"); asteroid aster_obj = obj_aster; spaceship ship_obj = obj_ship;
ç§ãã¡ã¯ãã§ãã¯ããŸãïŒ
nullã®ãã¹ãïŒ
aster_obj.is_nullïŒïŒïŒfalse
ship_obj.is_nullïŒïŒïŒfalse
ããŒã¿ã¯ã©ã¹ã®ãã¹ãïŒ
aster_obj.data_classïŒïŒïŒå°ææ
ship_obj.data_classïŒïŒïŒå®å®è¹
ãã¹ãèå¥ïŒ
aster_obj.get_identifierïŒïŒïŒ67890
ship_obj.get_nameïŒïŒïŒãªã¡ã¬ãžã¥ãªãšãã
ååŸã«ã ããŒã«ãã³ã®ããã«ãã¯ããã«çãã ãã§ãã
ä»£å ¥æŒç®åããã¹ãããããšãå¿ããªãã§ãã ããïŒ
aster = asteroid(335577); ship = spaceship("Ramambahara"); obj = object(); obj_aster = asteroid(446688); obj_ship = spaceship("Mamburu"); aster_obj = obj_aster; ship_obj = obj_ship;
ãããŠåã³ç¢ºèªããŸãïŒ
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
ããŒã¿ã¯ã©ã¹ã®ãã¹ãïŒ
aster.data_classïŒïŒïŒå°ææ
ship.data_classïŒïŒïŒå®å®è¹
obj.data_classïŒïŒïŒnull
obj_aster.data_classïŒïŒïŒå°ææ
obj_ship.data_classïŒïŒïŒå®å®è¹
aster_obj.data_classïŒïŒïŒå°ææ
ship_obj.data_classïŒïŒïŒå®å®è¹
ãã¹ãèå¥ïŒ
aster.get_identifierïŒïŒïŒ335577
ship.get_nameïŒïŒïŒRamambahara
aster_obj.get_identifierïŒïŒïŒ446688
ship_obj.get_nameïŒïŒïŒãã³ãã«
ãã¹ãŠãæ£åžžã«æ©èœããŸãïŒ ä»¥äžã¯sourceã䜿çšããGitHubãžã®ãªã³ã¯ã§ã ã
å©çïŒ
äœããããŸããïŒ ããã¯Pimplã§ã¯ãããŸãããPimplã«ã¯å€åãå€ãããããããå®è£ ãã€ã³ã¿ããšããååã¯æé©ã§ã¯ãããŸããã C ++ã§ã¯ãå®è£ ã¯ã¯ã©ã¹å®£èšãšã¯å¥ã§ãã.cppãã¡ã€ã«ã§ã¯ãPimmplã䜿çšããŠããŒã¿ãå®è£ ã«å ¥ããããšãã§ããŸãã ããã§ãããŒã¿ã¯å®è£ å ã«é ãããŠããã ãã§ãªããéå±€ããªãŒã圢æããã€ã³ã¿ãŒãã§ã€ã¹ã¯ã©ã¹ã®éå±€ããã©ãŒãªã³ã°ããŠããŸãã ããã«ãnullå€ã®ã«ãã»ã«åãååŸããnullå€ã®æå¹æ§ã®ããžãã¯ã掟çã¯ã©ã¹ã«åã蟌ãããšãã§ããŸãã ãã¹ãŠã®ã¯ã©ã¹ã¯ç°¡åã«ããŒã¿ãšããåãã§ããŸã-ç¬èªã®ã¯ã©ã¹ãšç¥å ãšç¶æ¿è ã®ãã§ãŒã³å šäœã®äž¡æ¹ã§ãããæ§æèªäœã¯ã·ã³ãã«ã§ç°¡æœã§ãã
ã©ã€ãã©ãªAPIã ããå®è¡ãããã§ããïŒ ä»ã§ã¯äœãæ°ã«ããŸããã C ++ãéåžžã«è€éã§ããããã®äžã«é«ã¬ãã«ã®ããžãã¯ãäœæããããšã¯äžå¯èœã§ããã¬ããªã«ã«ã€ããŠã¯ããã®ãããªãªããžã§ã¯ãã®é åãçµåããããšãã§ããCïŒãŸãã¯Javaãããæªããªããå€æã¯ããã«ç°¡åã«ãªããŸãã åºæ¬ã¯ã©ã¹ãžã®ãã€ã³ã¿ãŒãä¿åããå¿ èŠãªãããã¡ã¯ããªãŒããããå¿ èŠãªããã¯ã©ã¹ã䜿ããããããããšãã§ããŸããäžè¬ã«ãéåžžã®ã³ã³ã¹ãã©ã¯ã¿ãŒãä»£å ¥æŒç®åãããããæ¹æ³ã§ãšãã¥ã¬ãŒãããå¿ èŠã¯ãããŸããã
䟿å©ãªãªã³ã¯
ãã®èšäºã«ã¯ã GitHubã«æçš¿ããããœãŒã¹ã³ãŒããä»å±ããŠããŸãã
ãœãŒã¹ã¯ããã¹ããç°¡çŽ åãããªããžã§ã¯ãéã®ããŒã¿è»¢éãã©ã®ããã«æ©èœãããããã°ããç解ã§ããããã«ããããã€ãã®æ¹æ³ã«ãã£ãŠè£å®ãããŸãã
ãŸããHackerãã¬ãžã³ã®C ++ Academyã·ãªãŒãºã®èšäºãžã®ãªã³ã¯ãæ®ããŸãã