C++ã§ã¯åºåºã¯ã©ã¹ã«virtualãã¹ãã©ã¯ã¿ãæ¸ãã
(追è¨ãã/å追è¨ãã)
ãã¯ãçµç±ã§ãC++ã§æ¼ç®åãªã¼ãã¼ãã¼ãããã¨ãã®æ¼ç®å決å®åºæºã«ã¤ãã¦èª¿ã¹ãã¨ããã®ãè¦ãã®ã ãã©ãæ¸ãã¦ãããµã³ãã«ã³ã¼ããæ¼ç®åãªã¼ãã¼ãã¼ã以åã«ã¡ãã£ã¨ãã¡ã ã£ãã
ææ¸ãããã¹ãã³ã¼ãã¨æ¸ãã¦ããã®ã§ãä»ã¯åãã£ã¦ãã®ãããããªããã©ãããç¨åº¦çµé¨ãç©ãã C++ããã°ã©ãã¯çµ¶å¯¾ã«(ã¨ããã®ã¯è¨ãããã§ãã)virtualãã¹ãã©ã¯ã¿ã®ãªãã¯ã©ã¹ãç¶æ¿ããªã(追è¨ãTBããã³ã¡ã®è°è«ãåç
§ã®ãã¨)ã®ã§ããã®ãµã³ãã«ã³ã¼ããè¼ãã¦éåæãæããªãæç¹ã§ãæ¼ç®åãªã¼ãã¼ãã¼ããããããããã¾ãã¯Effective C++ãèªãã æ¹ãããã
ä½ããã¡ãã以ä¸ã®ããã«ãvirtualãã¹ãã©ã¯ã¿ããªãã¯ã©ã¹ãç¶æ¿ãã¦ãããããã¯ãã¡ã ãä¾ãåºåºã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã§ãã¹ããã¨ããªãã®ã ã¨ãã¦ããç¶æ¿ããã¤ããã®ããã¯ã©ã¹ã«ã¯virtualãã¹ãã©ã¯ã¿ãä½ããªãã¨ãããªãã
å
è¨äºã®æ¬é¡ã§ããvirtualã®æåã«ã絡ãã®ã ãã©ãåºåºã¯ã©ã¹ã«virtualãã¹ãã©ã¯ã¿ããªãã¨ãdeleteã¾ãã¯ã¹ã³ã¼ããå¤ãã¦ç ´å£ãããã¨ãã®åã«å¿ãã¦ãµãã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ãå¼ã°ãããå¼ã°ããªãã£ãããã*1ã
#include<iostream> using std::cout; using std::endl; class BadBase { public : BadBase(){} //FIXME virtualãã¹ãã©ã¯ã¿ããªããï¼ï¼ }; class BadSub : public BadBase{ public : BadSub(){ cout << "ãªã½ã¼ã¹ç¢ºä¿ãã¾ãã" << endl; } ~BadSub(){ //ä½ããªã½ã¼ã¹ãéæ¾ãã cout << "ãªã½ã¼ã¹éæ¾ãã¾ãã" << endl; } }; int main(){ BadSub* sub = new BadSub(); //"ãªã½ã¼ã¹ç¢ºä¿ãã¾ãã" delete sub; //"ãªã½ã¼ã¹è§£æ¾ãã¾ãã" BadBase* base = new BadSub(); //"ãªã½ã¼ã¹ç¢ºä¿ãã¾ãã" delete base; //ãªã½ã¼ã¹ãéæ¾ãããªãï¼ return 0; }
ããã§ã¯å°ããã§ã¯æ£ããã¯ã©ããããã
çãï¼
ç¶æ¿ããå¯è½æ§ã®ããã¯ã©ã¹ã«ã¯ãã¹ã¦virtualãã¹ãã©ã¯ã¿ãä½ã
#include<iostream> using std::cout; using std::endl; class Base { public : Base(){} //ä¾ããããã¨ããªãã¦ããåºåºã¯ã©ã¹ã«ã¯virtualãã¹ãã©ã¯ã¿ãå¿ è¦ virtual ~Base(){} }; class Sub : public Base{ public : Sub(){ cout << "ãªã½ã¼ã¹ç¢ºä¿ãã¾ãã" << endl; } virtual ~Sub(){ //ä½ããªã½ã¼ã¹ãéæ¾ãã cout << "ãªã½ã¼ã¹éæ¾ãã¾ãã" << endl; } }; int main(){ Sub* sub = new Sub(); //"ãªã½ã¼ã¹ç¢ºä¿ãã¾ãã" delete sub; //"ãªã½ã¼ã¹è§£æ¾ãã¾ãã" Base* base = new Sub(); //"ãªã½ã¼ã¹ç¢ºä¿ãã¾ãã" delete base; //"ãªã½ã¼ã¹è§£æ¾ãã¾ãã" return 0; }
C++ã§ã¯ãvirtualãã¹ãã©ã¯ã¿ã®ãªãã¯ã©ã¹ã¯ç¶æ¿ããã¤ããã®ãªãã¯ã©ã¹ï¼Javaã§ããfinalã¯ã©ã¹ï¼ã§ããã¨èããæ¹ãããã
éã«ãC++ã§virtualãã¹ãã©ã¯ã¿ããªãã¯ã©ã¹ãç¶æ¿ãã¦ããã³ã¼ããè¦ããï¼ã¨ãããvirtualãã¹ãã©ã¯ã¿ããªãã¯ã©ã¹ãè¦ããï¼ãã®ã³ã¼ãã¯çã£ã¦ãããã¹ãã§ããã
C++ã«ã¯ãã®ãããªè½ã¨ãç©´ãå±±ã»ã©ãããEffective C++ã¨ããæ¸ç±ãããã®ãããªè½ã¨ãç©´ãæåä¸å¯§ã«èª¬æãã¦ããã®ã§ãããã°ã©ãã³ã°è¨èªC++ãèªã¿ãããªãã¨æããã¨ãã¦ããC++ããã°ã©ãã¯ã¾ãEffective C++ãèªãã¹ãã ã<追è¨>
ã³ã¡ã³ãã¨ããã³ã¡ã¨ãTBã§è²ã
çªã£è¾¼ã¿ãããã ããã®ã§åå¿ã
ããç¨åº¦çµé¨ãç©ãã C++ããã°ã©ãã¯çµ¶å¯¾ã«virtualãã¹ãã©ã¯ã¿ã®ãªãã¯ã©ã¹ãç¶æ¿ããªãï¼
ç¶æ¿åæã§ãããã¤ä»®æ³ãã¹ãã©ã¯ã¿ãæ¸ãã¹ãã§ãªãåä¾ã®Uncopyableã¯ã©ã¹ã¯ç«¯çã§ç´ æ´ãããã¨æãã¾ããã
ãªãã¨ããããåã¯ãå®è£
ç¶æ¿(Privateç¶æ¿)ã¯ã©ã¡ããã¨ããã¨æªã ãã¿ãããªã¤ããªãã®ã¼ãæã£ã¦ããï¼ãï¼ã®ã§ãã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã代å
¥ãç¦æ¢ããã®ã«Privateç¶æ¿ã使ãã£ã¦ã®ã¯èãããã¨ããªãã£ãã§ãã確ãã«Uncopyableãã¤ã³ã¿ãä»ãã¦ãªãã¸ã§ã¯ããç ´å£ãããã¨ã¯ãªããããªã®ã§ç´ æ´ãããä¾ã§ãããåå¼·ã«ãªãã¾ããã
ï¼ããç¨åº¦çµé¨ãç©ãã C++ããã°ã©ãã¯çµ¶å¯¾ã«virtualãã¹ãã©ã¯ã¿ã®ãªãã¯ã©ã¹ãç¶æ¿ããªã
ããã¾ã§è¨ã£ã¡ããã¨ããã¯ããã§ãã¦ãï½
C++ã®æ ¹åºã®ææ³ã®ã²ã¨ã¤ã§ããã¼ããªã¼ãã¼ãããã®å©çã享åããçºã«ãç´æ¥ new/delete ãããã¨ã¯ãªãã¯ã©ã¹ãªãç¶æ¿ãããã¨ãåæã§ãã£ã¦ããã¹ãã©ã¯ã¿ã« virtual æå®ã¯ãã¾ããããã(
id:wraith13ãã
ããã¯ããéãããªã¨ãæã£ãã®ã§ãããããã¾ã§ç´°ãã話ãåããããã説æããèªä¿¡ããªãã£ãï¼ä¸è¨Uncopyableã®ãããªä¾ãæãã¤ããªãã£ãã®ã§ãããªæãã«ãªãã¾ããã
åã¯å¯è±ªçãªç°å¢ã§ããä»äºãã¦ãã¦ãªãã®ã§ãvtblã®ã¡ã¢ãªæ ¼ç´ãå¼ã³åºããªã¼ãã¼ããããæ¯é
çã«ãªããããªç¶æ³ã«ãªãã¾ã§ã¯ããã®è¾ºã¯å¯è±ªçã«è¡ããã¨æã£ã¦ãã¾ããã
çµå±C++ãæ¸ããªããªãã¾ã§ããããç¶æ³ã«ï¼åã¯ï¼ãªããªãã£ãã®ã§ãªã¼ãã¼ãããã«é¢ãã¦ã¯å²ã¨è»½è¦ãã¦ãã¦ããããããå¤å°ã®ãªã¼ãã¼ãããããã£ã¦ãåãããããã¦èªåã®è¶³ãæã¡æããã¨ã¯ãªãã«ã¼ã«ã®æ¹ãããããªãã¿ããã«èãã¦ã¾ããã
ãã¡ããã¢ã¼ããã¯ãã£çã«å¦çãåæ£ããã¨ãåç´ã«ã¹ã±ã¼ã«ã¢ãããããã¨ãã§ããå¯è±ªçç°å¢ã§ããéç¨ããªãã«ã¼ã«ãªã®ã§ãããã
C++ã¯C++ã¨ãã¦ä½¿ãã¾ãããï¼
ã¨ããããããã
C++ã£ã¦ãã¾ãã«ãæ©è½ï¼ã¨è½ã¨ãç©´ï¼ãå¤ãããã®ã§ãå
¨æ©è½ã使ãåããã¨ã¯ãã¾ãæã£ã¦ãªãã®ã§ããã
vtblãªã¼ãã¼ãããã¨ãã®è©±ã¿ããã«ããããå¿
è¦ã«ãªã£ãã¨ãã«è½ã¨ãç©´ã¨ä¸ç·ã«ã¡ããã¨åå¼·ããã°ããããªã¨ã
ã絶対ã«ãã¯å¤§åãããã¯è½ã¨ãç©´ã§ãC++æ¬ é¥ã§ããªããã¹ãã©ã¦ã¹ãã©ããããªã«ãèãã¦ããããä»æ§ã«ããã®ãç¥ã£ã¨ãã¹ãã ãï¼å人çã«ã¯vtblããªããã¨ãä¿éãã修飾åãä½ããããã°ããã£ããã ã¨æãï¼
id:meg_nakagamiããã®ãã³ã¡
ä»°ããããã¨ã¯id:wraith13ããã¨åãããªãåã®ææ³ãåãããã¨vtblãªããä¿è¨¼ãã/æå®ãã修飾åçãããã°ããã£ãã¨ããã®ã¯ãããåæãã¾ãã追è¨>
<å追è¨>
ããç¨åº¦ã®çµé¨ï¼
std::unary_functionã¯ç¥ããªãã£ãã®ã§åå¼·ã«ãªãã¾ããC++ããã£ã¦ãããã¯é¢æ°åè¨èªãå
¨ç¶ç¥ããªãã£ãã®ã§functionalãããã«å
¥ã£ã¦ãã¢ãã¯å
¨ç¶ãã§ãã¯ãã¦ã¾ããã§ããã
ãã ããã®ä¾ã®std::unary_functionã¨ãstd::binary_functionã¨ãã¯æ¬å½ã«virtualãã¹ãã©ã¯ã¿ããªãè¨è¨ã§ããã®ï¼ã¨ããç¹ã¯ã¡ãã£ã¨çåã§ããã
ä¾ãã°std::unary_functionã®æ´¾çã¯ã©ã¹ã¨ãã¦ããç°å¢ã¸ã®åç
§ãæã¤é¢æ°(ã¤ã¡ã¼ã¸ã¨ãã¦ã¯ã¯ãã¼ã¸ã£)ããä½ã£ã¦ããã¤ã¯ãã¹ãã©ã¯ã¿ã§ä½ããããªãã¨ãã¡ã ã¨ãã¦ãunary_functionãªãã¸ã§ã¯ãã¨ãã¦ã³ã³ããã«ã¤ã£ããã§ä½ãããå¾ã«ããªãã¸ã§ã¯ããunary_functionã¨ãã¦ç ´å£ããã¨ä¸å®ãªåä½ã«ãªãã¨ããã®ã¯ã¡ãã£ã¨ä¸å®ã«æãã¾ãã
ãããã使ãæ¹ã¯æ³å®å¤ãªãã§ããããã
絶対ã«ã¨ããã®ã¯ããããã¾ãªè¨ãéãã«ãããä¸è¬è«ã¨ãã¦ãç¶æ¿ããã¤ããã®ããã¯ã©ã¹ã§ã¯åºæ¬çã«virtualãã¹ãã©ã¯ã¿ãç¨æãããããããªãã®ãªãã°ãèªåãä½ããããã¨ãã¦ãããææ¡ããä¸ã§ããããã¨ãã£ãã¨ãããªãã°å¦¥å½ãªè½ãã©ããã¨ããããã§ããï¼å追è¨>
*1:ç¾å®ã¯ãã£ã¨éæ ã§ããããã®å ´åã®åä½ã¯ä¸å®ã§ãããEffective C++第äºçã®è¡¨ç¾ãåããã°ãC++æ¨æºè¦æ ¼ã¯ããã®ç¹ã«ã¤ãã¦æ¥µãã¦æ確ã«è¿°ã¹ã¦ãããåºåºã¯ã©ã¹ã®ãã¤ã³ã¿ãä»ãã¦æ´¾çã¯ã©ã¹ã®ãªãã¸ã§ã¯ããåé¤ãããã¨ããã¨ãããã®åºåºã¯ã©ã¹ã«ä»®æ³ã§ãªããã¹ãã©ã¯ã¿ãããã¨ããã®çµæã¯ä¸å®ã¨ãªããä¸å®ã¨ã¯ããªãã¡ãã³ã³ãã¤ã©ã¯ã©ããªã³ã¼ãã§ã好ãåæã«çæãã¦ãããã¨ããæå³ã§ããããé¼»ããæªéãé£ã³åºã¾ãã