
åŸæ¥ã®OOPã®æ¬ ç¹ãåãé€ããã¢ãžã¥ã©ãŒã¹ã¿ã€ã«ã§C ++ã§èšè¿°ããŸãã
éåœã«ãã£ãŠãç§ã¯C ++ã§èšè¿°ãããäžçšåºŠã®è€éãã®ãããžã§ã¯ãããµããŒãããã³éçºããå¿
èŠããããŸããã ãã®ãããžã§ã¯ãã¯ãå€å
žçãªOOPã¹ã¿ã€ã«ã§èšè¿°ãããŠãããã¢ãžã¥ãŒã«ãšã¯ã©ã¹ã«ãã£ãŠé©åã«æ§æãããŠããŸãã ãã®åã«ãJavaãšApache Tapestry 5ã§ãããžã§ã¯ããéçºããã®ã«å€ãã®æéãè²»ããããšèšããªããã°ãªããŸãããç¹ã«ãIOCã³ã³ãããŒã®ã€ããªãã®ãŒãéåžžã«ããçè§£ããŸããã ãããã£ãŠãããã€ãã®ã¢ã€ãã¢ãããããã³ããŒãããŸãã
ãã®ããããããžã§ã¯ãã¯æ§é åãããŠããŸãããã»ãšãã©ãã¹ãŠã®ããããŒãã¡ã€ã«ã«å°ããªå€æŽãå ãããšããããžã§ã¯ãã®ååãåã³ã³ãã€ã«ãããŸãã ã³ãŒããèšè¿°ãããšãã®æ§æã®è©³çްã«ã¯ç¹ã«æ³šæããŠããŸããïŒããããŒãåå空éãªã©ãå«ããã®ãå¿ããããšã¯ç§ã«ãšã£ãŠã¯æ®éã§ãïŒã ãããã£ãŠãç§ã¯å
±æãããã³ã³ããŒãã³ãã³ãŒãã®æ¥ç¶æ§ãæžããããã«ããããžã§ã¯ãã«ããã€ãã®ãã©ã¯ãã£ã¹ãå®è£
ããããšã«ããŸããã ããã«èŠåãåºãããã§ãã ãã®ãããžã§ã¯ãã«ã¯C ++ 98ãšã®äºææ§ãå¿
èŠãªããããã®ç¯å²ãè¶
ãããã®ã¯ãã¹ãŠBoostã䜿çšããŠå®è£
ãããŸãã
å¯å€å¯¿åœ
OOPã®åºæ¬ååã®1ã€ã¯ã«ãã»ã«åã§ãã ããã«ã¯ã倿°ã䜿çšãããŠããå Žåã«ã®ã¿å€æ°ã䜿çšå¯èœã«ãããšããã«ãŒã«ãå«ãŸããŠããŸãã å¯çšæ§ã¯ãèªå倿°ã®å¯¿åœãšã»ãŒåçã§ãã ãããã£ãŠãã¿ã€ã
MyStack
倿°ãã¯ã©ã¹Aã®ãã©ã€ããŒãã¡ã³ããŒã§ããå Žåãã¯ã©ã¹ã®ãã¹ãŠã®ãŠãŒã¶ãŒã¯ããããŒMyStack.hã®ã€ã³ããŒãã匷å¶ãããŸãã ãã®å€æ°ã1ã€ã®é¢æ°ã®ã¿ã§äœ¿çšãããç¶æ
ãå«ãŸããŠããªãå Žåã¯ãäžè¬ã«éç倿°ã«ããå¿
èŠããããŸãã ããã«ããããã¯ã®æåŸãŸã§èªå倿°ãååšããããšãå¿ããªãã§ãã ãããããã䜿çšããŠãã³ãŒããããã¯ã«ãã£ãã远å ããããšã§ãäžèŠãªå€æ°ãããã«ç Žæ£ããŸãã
PImpl
ã¯ã©ã¹ã®ãã©ã€ããŒãéšåã®å®è£
ãé ãåé¡ã¯ãå®è£
ãã€ã³ã¿ïŒPimplïŒã«ãã£ãŠéšåçã«è§£æ±ºãããŸãã ãã®ããŒãã«é¢ããèšäºã¯ååã«ããã®ã§ãPimmplã«ã€ããŠè©³ãã説æããããããŸããã ããšãã°ããµãã¿ãŒã®çŽç« ïŒ
ã³ã¡ã³ããäœæããã€ãã£ãªã ã®å®è£
ã®ã¿ãè¡ããŸãã
- ãã®ã€ãã£ãªã ã¯ãå®è£
çšã®ãã©ã¡ãŒã¿ãŒãåãåããããªãã¯ã³ã³ã¹ãã©ã¯ã¿ãŒãé ããŸããã ãã®åé¡ã¯ããªããžã§ã¯ãã®ã€ã³ã¿ãŒãã§ã€ã¹ãšãã¡ã¯ããªãçµã¿åãããããšã§è§£æ±ºã§ããŸãã
- ã¢ãžã¥ãŒã«ã®ã€ã³ã¯ã«ãŒãã®ãããªãã¯éšåã«äžèŠãªãã®ããã¹ãŠãå®è£
ãšãšãã«ç§»åããããšãå¿ããªãã§ãã ããã
- äœåãªã³ãŒããç®ããé ãããã«ãC ++ 98ãšäºææ§ã®ããPImplã¢ãžã¥ãŒã«ãå®è£
ããŸãã
ã³ãŒã #ifndef PIMPL_H #define PIMPL_H
- ãã¹ãŠã®ã¯ã©ã¹ã§ãå®è£
宣èšã¯æ¬¡ã®ããã«ãªããŸã
class Impl; PImpl<Impl> me;
me
ã¯VBAããåããŸãã
- ïŒãããªãã¯ã¡ãœãããåŒã³åºãããã«ïŒãããªãã¯éšåãžã®ãã€ã³ã¿ãŒãå¿
èŠãªå Žåããããªãã¯
this
ã¯æåã®ãã©ã¡ãŒã¿ãŒImpl
ã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ããã ppub
ãã£ãŒã«ãã«æ ŒçŽãããŸã
- å®å
šãªå®£èšãæã€å®è£
ã¯ãçŸåšã®ã¢ãžã¥ãŒã«ã«ã®ã¿ã¹ã³ãŒãããããããåžžã«
struct
ãšããŠå®£èšãããŸãã
- éåžžãå®è£
ã«ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒãšããããªãã¯ã³ã³ã¹ãã©ã¯ã¿ãŒãå®å
šã«ç¹°ãè¿ããªãŒããŒããŒããªãã¬ãŒã¿ãŒãå¿
èŠã§ãã ã³ããŒã³ã³ã¹ãã©ã¯ã¿ãš
operator=
ã«ã€ããŠã¯ã me
ãšppub
èšå®ããããšãå¿ããªãã§ãã ããã
- Javaã¹ã¿ã€ã«ã®Impl颿°å®£èšã ãåç¥ã®ããã«ãã¯ã©ã¹ã§ããã«å®£èšããã³å®çŸ©ããã颿°ã¯ã€ã³ã©ã€ã³é¢æ°ã§ãã ã€ã³ã©ã€ã³ã¯ã³ã³ãã€ã©ãŒãžã®åãªãã¢ããã€ã¹ã§ãããèæ
®ã«å
¥ããŠããªãå¯èœæ§ãããããšãå¿ããŠã¯ãªããŸããããããã£ãŠãå€§èŠæš¡ãªé¢æ°ã¯ã€ã³ã©ã€ã³åãããªãå¯èœæ§ãé«ããªããŸããã颿°ã®å®£èšãšå®çŸ©ã®å®åæã¯å°ãªããªããŸãã
- åäœãã¹ãã«ã€ããŠã ãåãã®ããã«ããŠããããã¹ãã§ã¯ããã¹ã察象ã®ã¢ãžã¥ãŒã«ãäŸåããå®è£
ã®ä»£ããã«ã¹ã¿ããå¿
èŠã«ãªãããšããããããŸãã ã³ãŒããäŸåãããªããžã§ã¯ãã
PImpl
ã§å®è£
ãããŠããå Žåããªã³ã«ãŒã䜿çšããŠå®éã®å®è£
ãã¹ã¿ãã«éåžžã«ç°¡åã«çœ®ãæããããšãã§ããŸãã é ãããå®è£
ã®ãã¹ãã¯ãïŒincludeãã£ã¬ã¯ãã£ãã䜿çšããŠãã¹ãã¢ãžã¥ãŒã«ã«å®è£
ã³ãŒããå«ããããšã§å¯èœã§ãã
äžèšã®å
æ¬çãªäŸ ------- Hasher.h ------ #include <PImpl.h> class Hasher { class Impl; // class struct PImpl<Impl> me; // public: Hasher(); void execute(); int getResults(); }; ------- Hasher.cpp ------ #include âHasher.hâ #include <HashLib.h> #include âSecTokens.hâ // . struct struct Hasher::Impl { Hasher* ppub; // HashContext cnt; int hash; Impl(Hasher* ppub): ppub(ppub) { } void prepare() { HashLib::createContext(cnt); hash = 0; } void update(int val) { HashLib::updateHash(cnt, hash, val); } void finalize() { HashLib::releaseContext(cnt); } }; Hasher::Hasher(): me(this) { // } void Hasher::execute() { me->prepare(); me->update(SecTokens::one); me->update(SecTokens::two); me->finalize(); } int Hasher::getResults(){ return me->hash; } ------- Cryptor.h ------ #include <string> #include <PImpl.h> class Cryptor { class Impl; PImpl<Impl> me; public: Cryptor(std::string salt); std::string crypt(std::string plain); }; ------- Cryptor.cpp ------ #include <CryptoLib.h> #include âCryptor.hâ struct Cryptor::Impl { std::string salt; CryptoContext cnt; Impl(std::string salt): me(salt) { } void prepare() { CryptoLib::createContext(cnt); } void update(std::string plain) { CryptoLib::updateHash(cnt, plain); } std::string finalize() { return CryptoLib::releaseContext(cnt); } }; Cryptor::Cryptor(std::string salt): me(salt) { } std::string Cryptor::crypt(std::string plain) { me->prepare(); me->update(plain); return me->finalize(); } ------- MockHasher.cpp ------ #include âHasher.hâ struct Hasher::Impl { }; void Hasher::execute() { } int Hasher::getResults(){ return 4; } ------- TestCryptor.cpp ------ #include âCryptor.cppâ int main(int argc, char** argv) { Cryptor::Impl impl(âsaltâ); impl.prepare(); // impl prepare impl.update(âtextâ); // impl update std::string crypto=impl.finalize(); // crypto }
ãããã£ãŠããã¹ããèšè¿°ããå¿
èŠãããCryptoLib
ã¯ã©ã¹ïŒç¹å®ã®HashLib
ã©ãããŒïŒãšã Cryptor
äŸåããHasher
ã¯ã©ã¹ïŒç¹å®ã®HashLib
ã©ãããŒïŒããããŸãã ãã ãã Cryptor
äŸç¶ãšããŠHashLib
ããã³SecTokens
ã«äŸåããŠããã Cryptor
ãã¹ãã§ã¯çµ¶å¯Ÿã«ãããå¿
èŠãšããŸããã 代ããã«ãMockHasher.cppãæºåããŸãã
Cryptor.cppã³ãŒãã¯TestCryptor.cppã«å«ãŸããŠããããããã¹ãããã«ãããã«ã¯ãTestCryptor.cppãšMockHasher.cppã®ã¿ãã³ã³ãã€ã«ããŠæ§æããŸãã ããã¯ãã®èšäºã®ãããã¯ã§ã¯ãªãããããŠããããã¹ãã©ã€ãã©ãªã«åºã¥ããäŸã瀺ããŸããã
ããããŒãã¡ã€ã«ã®å
å«ã®æ¹èš
ããã§ã¯ç°¡åã§ãã ããããŒã¯ãã³ãŒãã®åæäžã«ã§ããã ãé
ãå«ããå¿
èŠããããŸãããã§ããã°ãã¡ã€ã«ã®å
é ã«å«ããå¿
èŠããããŸãã ã€ãŸã ã¯ã©ã¹å®è£
ã®ã¿ããµãŒãããŒãã£ããããŒã䜿çšããå Žåãã¯ã©ã¹ããããŒããã¯ã©ã¹å®è£
ã¢ãžã¥ãŒã«ã«è»¢éããŸãã
ãããªãã¯é¢æ°ã®ä»£ããã«ã³ãŒã«ããã¯ãšãã¡ã³ã¯ã¿ãŒ
ãã®ãããžã§ã¯ãã«ã¯ããã©ãããã©ãŒã ã«äŸåãããã¹ãŠã®æ©èœãäœæããã¢ãžã¥ãŒã«ããããŸãã
Platform
ãšåŒã°ã
Platform
ã åã
platform
åå空éã§å®£èšããé¢é£ã®ãªã颿°ãæã€ã¢ãžã¥ãŒã«ã倿ããŸããã å°æ¥çã«ã¯ããã©ãããã©ãŒã ã«å¿ããŠã¢ãžã¥ãŒã«ãå®è£
ã«çœ®ãæããŸãã ããããããã«åé¡ããããŸãã 颿°ã®1ã€ã¯ãäžè¬ã«å¥ã®ãããªãã¯ã¯ã©ã¹
Settings
ãã©ã€ããŒãéšåã§å®£èšãããã¯ã©ã¹ã®<keyãvalue>ãã¢ïŒããã¯
std::map
ã§ãããç¹å®ã®ã³ã³ãã¬ãŒã¿ãŒã䜿çšïŒãåããå¿
èŠããããŸãã
ãã©ã€ããŒãã¯ã©ã¹ããããªãã¯ã«ãããã©ãããã©ãŒã ããããŒãè€æ°ã®ããããŒã«åå²ã§ããŸãã ãã®å Žåãfill颿°ã¯ããã®fillã«é¢é£ããªãã¯ã©ã¹ã«ã¯å«ãŸããããã®
std::map
äŸåããªããªã
std::map
ã ãã³ãã¬ãŒãã³ã³ãã¬ãŒã¿ã®ã¹ã³ãŒãããã©ã€ããŒãããããäžè¬çãªãã®ã«å€æŽãããšãã³ã³ããŒãã³ãã®æ¥ç¶æ§ãåäžããããšãé€ããŠãç§ã¯ããããŒãã¡ã€ã«ã®äœæãæ¯æããŸããã 倿Žãããšããã©ãããã©ãŒã åºæã®ãã¬ãŒã¹ãã«ããŒã«äŸåãããã¹ãŠãåã³ã³ãã€ã«ãããŸãã
å¥ã®æ¹æ³ã¯ã
boost::bind
ããã³callback颿°ã䜿çšãã
boost::bind
ã§ãã ãã¬ãŒã¹ãã«ããŒé¢æ°ã¯é¢æ°ãžã®ãã€ã³ã¿ãŒãåããŸã
void fillDefaults(boost::function<void(std::string, std::string) > setDefault);
ã®ä»£ããã«
void fillDefaults(std::map<std::string, std::string, ci_less>& defaults);
Settings
ã®ãã©ã€ããŒãéšåã«ã³ãŒã«ããã¯ãäœæããŸãã
void setDefault(std::string key, std::string value) { defaults[key] = value; } void fillDefaults() { platform::fillDefaults(boost::bind(&SettingsManager::Impl::setDefault, this, _1, _2)); }
ã®ä»£ããã«
void fillDefaults() { platform::fillDefaults(defaults); }
pimplã䜿çšãããšãåãååã®ãã©ã€ããŒãã®ã©ãããŒã®åœ¢åŒã§ãããªãã¯é¢æ°ãäœæããæ¹ã䟿å©ãªå ŽåããããŸãã äžèšã®é¢æ°ã䜿çšãã
void Hasher::execute() { me->prepare(); me->update(SecTokens::one); me->update(SecTokens::two); me->finalize(); }
ãšããŠæ³åããããšãã§ããŸã
void Hasher::Impl::execute() { prepare(); update(SecTokens::one); update(SecTokens::two); finalize(); } void Hasher::execute() { me->execute(); }
ãããããã€ã³ããã¡ã³ã¯ã¿ã§ãããè¡ãããšãã§ããŸã
------- Hasher.h ------ #include <boost/functions.hpp> #include <PImpl.h> class Hasher { class Impl; // class struct PImpl<Impl> me; // public: Hasher(); boost::function<void()> execute; int getResults(); }; ------- Hasher.cpp ------ //âŠâŠ... Hasher::Hasher(): me(this), execute(boost::bind(&Hasher::Impl::execute, &*me)) { } int Hasher::getResults(){ return me->hash; }
颿°å®çŸ©ãåãé€ããŸãã
ããã§ã以åã®ããã«executeãåŒã³åºãããšãã§ããŸãã
void f(Hasher& h) { h.execute(); }
ãããŠãäŸãã°ãå®è¡ã®ããã«å¥ã®ããã©ãŒããŒã«éãããŸã
void f(Hasher& h, boost::asio::io_service& executor) { executor.post(h.execute); }
ã®ä»£ããã«
void f(Hasher& h, boost::asio::io_service& executor) { executor.post(boost::bind(&Hasher::execute, &h)); }
ã©ãããŒé¢æ°ã®ãã€ã©ãŒãã¬ãŒã宣èšã¯ãããŒã¹ããã¡ã³ã¯ã¿ãŒå®£èšã®ãã€ã©ãŒãã¬ãŒã宣èšã«å€æãããã³ã³ã¹ãã©ã¯ã¿ãŒã®ã¿ã«æ®ããŸããã
ã³ã€ã³ã«ã¯è£è¿ããããããšã«æ³šæããŠãã ããã
execute
ã¯ã©ã¹ã®ãããªãã¯ãã£ãŒã«ãã«ãªããå®è¡æã«æ°ããå€ã誀ã£ãŠå²ãåœãŠãããå¯èœæ§ããããŸãããããã¯é¢æ°ã§ã¯çºçããŸããã ãŸããä»®æ³ã¡ãœããã®éåžžã®ãªãŒããŒã©ã€ãã¯äœ¿çšã§ããªããªããŸãããããã®åé¡ã¯ç°¡åã«è§£æ±ºã§ããŸãã
ãããã£ãŠãJavaScriptã®ãããªé«é颿°ã®é
åãåŸãããŸãã
ã¡ã€ã³ãããã¯ã®ç¯å²ãè¶
ãããã¡ã³ã¯ã¿ãŒã«ã€ããŠã®ããå°ãã®èšèã ãã¡ã³ã¯ã¿ãäœæããããã«åºã¥ããŠå¥ã®ãã¡ã³ã¯ã¿ãããå°ãªãåŒæ°ã§äœæããããšããŸã
void myFunction(int, int); int main(int argc, char** argv) { boost::function<void(int, int)> functor1(boost::bind(myFunction, _1, _2)); boost::function<void(int)> functor2(boost::bind(functor1, 4, _1)); }
boost :: bindïŒfunctor1ã4ã_1ïŒã®ãã®åŒã³åºãã¯ãç®ãçããŸãã 颿°ãã€ã³ã¿ãšãã€ã³ããçµã¿åãããŠäœ¿çšââããªãã§ãã ããããããã¯å¥ã
ã«äœ¿çšãããããšã¯ãã£ãã«ãããŸããã æ¬¡ã«ãäžèšã®ã³ãŒãã¯æ¬¡ã®åœ¢åŒãåããŸãã
int main(int argc, char** argv) { Bindable<void(int, int)> functor1(boost::bind(myFunction, _1, _2)); Bindable<void(int)> functor2(functor1.bind(4, _1)); }
ãã€ã³ãå¯èœãªã³ãŒã #ifndef BINDABLE_H #define BINDABLE_H #include <boost/bind.hpp> #include <boost/function.hpp> template<typename Signature> struct Bindable : public boost::function<Signature> { Bindable() { } template<typename T> Bindable(const T& fn) : boost::function<Signature>(fn) { } template<typename NewSignature, typename A1> Bindable<NewSignature> bind(const A1& a1) { return boost::bind(this, a1); } // 2 9 template<typename NewSignature, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> Bindable<NewSignature> bind(const A1& a1, const A2& a2, const A3& a3, const A4& a4, const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, const A10& a10) { return boost::bind(*this, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); } }; #endif /* BINDABLE_H */
ã³ã³ã¹ãã©ã¯ã¿ãŒãªãã·ã§ã³ã®é èœ
æåã«ããã¶ã€ããŒãã©ã¡ãŒã¿ãŒã®ã¿ã€ããæ±ºå®ããå¿
èŠããããŸãã
- ç¹å®ã®ã€ã³ã¹ã¿ã³ã¹ã¢ããªã±ãŒã·ã§ã³ã®æ§æãã©ã¡ãŒã¿ã éåžžããããã¯ãã©ã°ãã©ââã€ã³ãã¡ããªãã¯ãªã©ã®åçŽãªã¿ã€ãã®ãã©ã¡ãŒã¿ãŒã§ãã ãã ãããããã®ãªãã·ã§ã³ãé衚瀺ã«ããããšã¯ã§ããŸããã
- å®è£
äœæ¥ã®ã°ããŒãã«ã¹ã³ãŒãããååŸãããªããžã§ã¯ãã ããã§ããããé衚瀺ã«ããŸãã
ããã€ã§ãã¢ã¯ã»ã¹ã§ããã®ã«ããªãã°ããŒãã«ã«ã¢ã¯ã»ã¹å¯èœãªãªããžã§ã¯ããã³ã³ã¹ãã©ã¯ã¿ãŒã«è»¢éããã®ãïŒããšããçåãçãããããããŸããã ã¯ããããã§ãã ããããããããªãã»ããè¯ãçç±ã¯ããã€ããããŸãã
- ã°ããŒãã«ãªããžã§ã¯ãã®ååŸã¯ãªãœãŒã¹ã倧éã«æ¶è²»ããæäœã«ãªãå Žåããããããã¯ã©ã¹ãã£ãŒã«ãã«ãã£ãã·ã¥ããããšããå§ãããŸã
- ã°ããŒãã«ãªããžã§ã¯ãã®ååŸã¯ãããšãã°
globalStorage.getProfiles().getProfile(âDefaultâ)
ãããªè€éãªæ§æãæã€ããšãã§ããŸãã ãã®ãããªåŒãç¹°ãè¿ããªãããã«ã¯ããªããžã§ã¯ããŸãã¯ãã®åç
§ãã¯ã©ã¹ãã£ãŒã«ãã«ä¿åããããšããå§ãããŸã
- ã°ããŒãã«ãªããžã§ã¯ãã®ã³ããŒã倿Žããå¿
èŠãããå ŽåããããŸãã æ¬¡ã«ãã³ããŒãã¯ã©ã¹ãã£ãŒã«ãã«ããå¿
èŠããããŸã
- ãããã°ç®çã§äœ¿çšæžã¿ãªããžã§ã¯ãã眮ãæããå¿
èŠãããå ŽåããããŸãã æ¬¡ã«ãã¯ã©ã¹ãã£ãŒã«ããžã®æœåºãšå²ãåœãŠã®åŒã³åºãã1åã ã倿ŽãããŸãã
ç¶æ¿ å·¥å Žãšã€ã³ã¿ãŒãã§ãŒã¹
ã€ã³ã¿ãŒãã§ã€ã¹ãšããŠçµ¶å¯Ÿæœè±¡ã¯ã©ã¹ã䜿çšãïŒããããŒãã¡ã€ã«ã§ååïŒãå¿
èŠãªã³ã³ã¹ãã©ã¯ã¿ãŒãã©ã¡ãŒã¿ãŒã䜿çšããŠç¶æ¿è
ãäœæãããšããã©ã¡ãŒã¿ãŒã®å
¬éãåé¿ã§ããŸãã ãã®å Žåããã¡ã¯ããªã䜿çšããŠã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã ããã¯ãã€ã³ã¿ãŒãã§ã€ã¹ã§å®£èšãããå®è£
ã¢ãžã¥ãŒã«ã§å®çŸ©ããããã¡ã¯ããªã¡ãœããããŸãã¯ãªããžã§ã¯ããæ°ãããªããžã§ã¯ããŸãã¯æ°ãããªããžã§ã¯ããžã®ãã€ã³ã¿ãè¿ãç¬ç«ããã¯ã©ã¹ã§ãã
é·ãéãç§ã¯ãç¶æ¿ãŸãã¯æ§æã䜿çšã§ããå Žåãæ§æãéžæãããšããäºå®ã«åŸåããŠããŸãã ããã«ãPure Virtual Function Calledãšã©ãŒãåãåãããšã§ããã®ã¢ãããŒãã®æ£ç¢ºæ§ã確信ããŸããã
æ§æ
pimplã€ãã£ãªã ãã¯ã©ã¹ã«å®è£
ãããŠããå Žåããã©ã€ããŒãå®è£
ãäœæãããšãã«ããããªãã¯éšåã®ã³ã³ã¹ãã©ã¯ã¿ãŒãã©ã¡ãŒã¿ãŒã§ã¯ãªããã°ããŒãã«ã¹ã³ãŒãã®ãªããžã§ã¯ãã«ã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ãããšãã§ããŸãã ã€ãŸã ãããªãã¯ã³ã³ã¹ãã©ã¯ã¿ãŒã«ã¯ã°ããŒãã«ãã©ã¡ãŒã¿ãŒã¯ãªãããã©ã°ã®ã¿ããããŸãã ã€ã³ã¹ã¿ã³ã¹ãäœæããã³ãŒãã»ã¯ã·ã§ã³ã§å®éã«ç¥ã£ãŠèšå®ããå¿
èŠããããã©ã¡ãŒã¿ãŒã
ãã¡ã€ã«ã®æ§é åãã¢ãžã¥ãŒã«åãé
å»¶åæå
ãããžã§ã¯ãã«ã¯ãçŽ50åã®ã.cppããã¡ã€ã«ãšããããŒãã¡ã€ã«ãå«ãŸããŠããŸãã ãã¡ã€ã«ã¯è«ççã«ãã£ã¬ã¯ããªïŒãµãã·ã¹ãã ïŒã«åå²ãããŸãã ã³ãŒãã«ã¯ãåçŽåã®ã°ããŒãã«å€æ°ãšããŠãŒã¶ãŒåã®å
±æãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ããããã®ãªããžã§ã¯ããå«ãŸããŠããŸãã ãªããžã§ã¯ããžã®ã¢ã¯ã»ã¹ã¯æ¬¡ã®ããã«ãªããŸã
globalStorage.getHoster()->invoke();
ãŸãã¯ïŒ
Profile pr=globalStorage.getProfiles()->getProfile(âDefaultâ);
äžèšã®
Platform
åæ§ã«ã
globalStorage
ã䜿çšãã
globalStorage
ããã¹ãŠã®å€éšã¿ã€ãã§
globalStorage
ã€ã³ã¿ãŒãã§ãŒã¹ããšã¯ã¹ããŒããããã®ãç¥ã
globalStorage
ãŸãã ãã ãã
GlobalStorage
ã¯ç¹å®ã®ã¿ã€ãïŒãŸãã¯ç¹å®ã®ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããïŒã®ãªããžã§ã¯ããå®éã«è¿ãå¿
èŠãããã
Platform
ãããªåé¡ã解決ããæ¹æ³ã¯ãããŸããã
ãããã£ãŠã次ã®ç®æšã¯ããµãã·ã¹ãã ãApache Tapestry 5 IOCã¢ãžã¥ãŒã«ã«äŒŒããã®ã«å€æããã°ããŒãã«ãªããžã§ã¯ãïŒä»¥éããµãŒãã¹ã¯TapestryãµãŒãã¹ã«äŒŒãŠããŸãïŒãžã®ã¢ã¯ã»ã¹ãç°¡çŽ åãããµãŒãã¹ã®æ§æãIOCã¢ãžã¥ãŒã«å
ã®å¥ã®ãã¡ã€ã«ã«è»¢éããããšã§ãã ãã®çµæãå®éã®ã³ã³ããŒãã³ããååŸããŸãïŒ
ã³ã³ããŒãã³ãæåããã°ã©ãã³ã°ãåç
§ïŒ
ããã«èšãããã®ã¯ãæ¬æ ŒçãªIOCã³ã³ããã®ããšã§ã¯ãªããšããããšã§ãã 説æããäŸã¯ãã·ã³ã°ã«ãã³ãµãŒãã¹ãã³ãã¬ãŒããšãã¡ã¯ããªã®äžè¬åã®ã¿ã§ãã ãã®ã¢ãããŒãã䜿çšããŠã
ã·ã£ããŠãµãŒãã¹ ïŒç¬ç«ãããµãŒãã¹ãšããŠãµãŒãã¹ãã£ãŒã«ãã衚ããŸãïŒããã³ãã®ä»ã®ãµãŒãã¹ãœãŒã¹ãå®è£
ããããšãã§ããŸãã
IOCã¢ãžã¥ãŒã«ãµãŒãã¹ã®æ§æ
äœæãã
代ããã«ä»
boost::shared_ptr<Hoster> hoster = globalStorage.getHoster();
ã³ãŒã«ã¯æ¬¡ã®ããã«ãªããŸã
InjectPtr<Hoster> hoster = ioc::resolve<Hoster>();
ã芧ã®ãšããããã®èšèšã§ã¯äœåãªãã®ã¯ã€ã³ããŒããããŸããã ã³ãŒãã§
Hoster
ãååŸããå¿
èŠãããå Žåã¯ãèªåã§ããããŒãã€ã³ããŒãããããã«æ³šæããå¿
èŠããããŸãã
resolve
ã¡ãœãããã³ãã¬ãŒãã®2çªç®ã®ãã©ã¡ãŒã¿ãŒã¯ããµãŒãã¹èå¥åã§ãã 1ã€ã®ã€ã³ã¿ãŒãã§ãŒã¹ãæã€è€æ°ã®ãµãŒãã¹ãããå Žåã«äœ¿çšãããŸãã
InjectPtr
ã¯ãé
å»¶ïŒé
å»¶ïŒåæåã䌎ããªããžã§ã¯ããžã®ã¹ããŒããã€ã³ã¿ãŒã§ãã
boost::shared_ptr
on
boost::shared_ptr
ãä¿åããããªããžã§ã¯ãã«å
éšçã«ä¿åããŸãã åŸè
ã¯ã
InjectPtr
æåã«åç
§è§£é€ããããšãã«åæåãããŸãã
InjectPtr
ã¯ãã¡ã¯ããªãã¡ã³ã¯ã¿ãåãåããä¿åããããªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã
InjectPtrã³ãŒã #ifndef INJECT_PTR_H #define INJECT_PTR_H #include <cassert> #include <cstddef> #include <boost/shared_ptr.hpp> #include <boost/scoped_ptr.hpp> #include <boost/make_shared.hpp> #include <boost/function.hpp> #include <boost/thread/mutex.hpp> ///Pointer to lazy instantiative object template<typename T> class InjectPtr { private: typedef boost::function<T*() > Factory; boost::shared_ptr< boost::shared_ptr<T> > px; boost::shared_ptr< boost::scoped_ptr<boost::mutex> > instantiateMutex; Factory factory; public: ///Main constructor. Take factory for future instantiate object InjectPtr(Factory factory) : px(boost::make_shared<boost::shared_ptr<T> >()) , instantiateMutex(boost::make_shared<boost::scoped_ptr<boost::mutex> >(new boost::mutex)) , factory(factory) { } InjectPtr() : px(boost::make_shared<boost::shared_ptr<T> >()) , instantiateMutex(boost::make_shared<boost::scoped_ptr<boost::mutex> >()) { } InjectPtr(boost::shared_ptr<T> pObject) : px(boost::make_shared<boost::shared_ptr<T> >(pObject)) { assert(*px != 0); } InjectPtr(InjectPtr const &orig) : px(orig.px) , instantiateMutex(orig.instantiateMutex) , factory(orig.factory) { } InjectPtr & operator=(InjectPtr const & orig) { px = orig.px; instantiateMutex = orig.instantiateMutex; factory = orig.factory; return *this; } virtual ~InjectPtr() { } T & operator*() { instantiate(); return **px; } T * operator->() { instantiate(); return &**px; } bool operator!() const { return !*px; } void operator==(InjectPtr const& that) const { return *px == that->px; } void operator!=(InjectPtr const& that) const { return *px != that->px; } boost::shared_ptr<T> sharedPtr() { instantiate(); return *px; } void instantiate() { if (!*px && factory) { { boost::mutex::scoped_lock lock(**instantiateMutex); if (!*px) { px->reset(factory()); } } instantiateMutex->reset(); } } Factory getFactory() const { return factory; } void setFactory(Factory factory) { if(!*px && !this->factory){ if(!*instantiateMutex) instantiateMutex->reset(new boost::mutex); this->factory = factory; } } }; template<class T, class U> InjectPtr<T> static_pointer_cast(InjectPtr<U> r) { return InjectPtr<T>(boost::static_pointer_cast<T>(r.sharedPtr())); } #endif /* INJECT_PTR_H */
InjectPtr
ã¹ã¬ããã»ãŒãã§ãã ãªããžã§ã¯ãã®äœæäžãæäœã¯ãã¥ãŒããã¯ã¹ã«ãã£ãŠãããã¯ãããŸãã
IOCæ§æãã¡ã€ã«ã«ç§»åããŸãã
ioc::resolve
ãå®å
šã«ç¹æ®åãã
ioc::resolve
ãã³ãã¬ãŒãã¡ãœããã
ioc::resolve
ã³ãŒã ------- IOCModule.h ------
GCCã¯ã颿°ã®éçããŒã«ã«å€æ°ãäœæããéã®ããã¯ãä¿èšŒããŸãã ããããæšæºã§ã¯ãããä¿èšŒãããŠããŸããã ã³ãŒãã倿Žãã
InjectPtr
ããŒããŒãã°ããŒãã«ãªéç倿°ã«é
眮ããå¿
èŠããããŸãããããã¯ããããããã°ã©ã ã³ãŒããå®è¡ãããåã§ãåæåãããŠããŸããã ãã¡ãããå¥ã
ã®å€æ°ã§ã§ããŸãããããããã®ååãäœæããå¿
èŠããããŸãã ããã§ã
CoreStorage
ã¯ã³ã¢IOCã¢ãžã¥ãŒã«ã®ããŒããŒã§ãã
IOCModule.cpp #include "Hoster.h" #include "SomeService.h" #include "InjectPtr.h" #include <IOCModule.h> #include <IOC.h> //Module like http://tapestry.apache.org/tapestry-ioc-modules.html //Now only for: - To provide explicit code for building a service using namespace ioc; struct CoreStorage { InjectPtr<SomeService> someService; InjectPtr<Hoster> hoster; }; static CoreStorage storage; ///methods like http://tapestry.apache.org/defining-tapestry-ioc-services.html#DefiningTapestryIOCServices-ServiceBuilderMethods template<> InjectPtr<SomeService> resolve<SomeService>() { if(!storage.someService.getFactory()) { storage.someService.setFactory(boost::bind(boost::factory<SomeService*>())); } return storage.someService; } ///Hoster takes SomeService in constructor template<> InjectPtr<Hoster> resolve<Hoster>() { if(!storage.hoster.getFactory()) { storage.hoster.setFactory(boost::bind(boost::factory<Hoster*>(), resolve<SomeService>())); } return storage.hoster; }
IOCã¢ãžã¥ãŒã«ããããŒãã¡ã€ã«
ãã®é
ç®ã¯ãIOCã¢ãžã¥ãŒã«å
ã®ã³ã³ããŒãã³ãã®æ¥ç¶æ§ããããã«å¢å ãããŸãããã¢ãžã¥ãŒã«éã®çžäºäœçšã«ããæžå°ããŸãã
IOCã¢ãžã¥ãŒã«ã®çžäºäœçšã®ããã«ãã¢ãžã¥ãŒã«èªäœãšåãååã®IOCã¢ãžã¥ãŒã«ã®ã€ã³ã¿ãŒãã§ã€ã¹ããããŒãäœæãããšäŸ¿å©ã§ãã 以äžãå«ãå¿
èŠããããŸãã
- ã¯ã©ã¹ã€ã³ã¿ãŒãã§ã€ã¹ã®IOCã¬ãã«ã¢ãžã¥ãŒã«ã§ã®publicã®å
å«ã
- IOCã¬ãã«ã®è»¢éããã³åçŽãªæ§é ã®ã¢ãžã¥ãŒã«ã§ã®å®å
šãªå®£èšã
- ããªããã»ããµå®çŸ©ã¢ãžã¥ãŒã«ã®IOCã¬ãã«ã§ãããªãã¯ã
ãŸãããããªãã¯ããããŒãã€ã³ããŒãããŠå®è¡ãããã©ã€ããŒãã¢ãžã¥ãŒã«ããããŒããããšäŸ¿å©ã§ãã
- ãããžã§ã¯ãã®ãã¹ãŠã®ã¯ã©ã¹ã®äºåçºè¡šã
- IOCã¢ãžã¥ãŒã«ããã³åçŽãªæ§é ã®å
éšè»¢éã®å®å
šãªå®£èšã
- IOCããªããã»ããµå®çŸ©ã¢ãžã¥ãŒã«ã®å
éšã