RTTI ±â´ÉÀº typeid ¿¬»êÀÚ·Î »ç¿ëÇÑ´Ù. ÀÌ ¿¬»êÀڴ Ŭ·¡½ºÀÇ À̸§À̳ª °´Ã¼ ¶Ç´Â °´Ã¼¸¦ °¡¸®Å°´Â Æ÷ÀÎÅ͸¦ ÇÇ¿¬»êÀÚ·Î ÃëÇϸç ÇÇ¿¬»êÀÚÀÇ Å¸ÀÔÀ» Á¶»çÇÑ´Ù. typeid ¿¬»êÀÚÀÇ ¸®ÅÏ Å¸ÀÔÀº const type_info & À̸ç type_info´Â Ŭ·¡½ºÀÇ Å¸ÀÔ¿¡ ´ëÇÑ Á¤º¸¸¦ °¡Áö´Â ¶Ç ´Ù¸¥ Ŭ·¡½ºÀÌ´Ù. ÀÌ Å¬·¡½º´Â ÄÄÆÄÀÏ·¯ Á¦Àۻ縶´Ù Á¶±Ý¾¿ ´Ù¸£°Ô Á¤ÀÇÇϴµ¥ ºñÁÖ¾ó C++ÀÇ °æ¿ì typeinfo Çì´õ ÆÄÀÏ¿¡ ´ÙÀ½°ú °°ÀÌ ¼±¾ðµÇ¾î ÀÖ´Ù.
class type_info {
public:
virtual ~type_info();
int operator==(const type_info& rhs) const;
int operator!=(const type_info& rhs) const;
int before(const type_info& rhs) const;
const char* name() const;
const char* raw_name() const;
private:
void *_m_data;
char _m_d_name[1];
type_info(const type_info& rhs);
type_info& operator=(const type_info& rhs);
};
name ¸â¹ö ÇÔ¼ö´Â ¹®ÀÚ¿·Î µÈ ŸÀÔÀÇ À̸§À» Á¶»çÇϴµ¥ Ŭ·¡½º À̸§À̶ó°í º¸¸é µÈ´Ù. raw_nameÀº Àå½Ä¸íÀ» Á¶»çÇϴµ¥ »ç¶÷ÀÌ ÀÐÀ» ¼ö ¾ø´Â ¹®ÀÚ¿À̹ǷΠºñ±³¿¡¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ÀÌ ¿Ü¿¡µµ type_info °´Ã¼°¡ °°ÀºÁö, ´Ù¸¥Áö¸¦ Á¶»çÇÏ´Â ==, != ¿¬»êÀÚ°¡ ¿À¹ö·ÎµùµÇ¾î Àִµ¥ Åë»ó == ¿¬»êÀÚ¸¸ »ç¿ëÇصµ ¿øÇϴ ŸÀÔÀÎÁö ¾Æ´ÑÁö¸¦ ¾Ë ¼ö ÀÖ´Ù.
¸¸¾à typeidÀÇ ÇÇ¿¬»êÀÚ°¡ NULL Æ÷ÀÎÅͷκÎÅÍ ÀÐÀº °ªÀÏ °æ¿ì bad_typeid ¿¹¿Ü¸¦ ¹ß»ý½ÃŲ´Ù. ¿¹¸¦ µé¾î p°¡ NULLÀÏ ¶§ typeid(*p) ¿¬»ê½ÄÀº ¿¹¿Ü·Î 󸮵ȴÙ. ¿¬»êÀÚÀÇ ¸®ÅÏ°ª¿¡´Â ƯÀÌ°ªÀÌ ¾øÀ¸¹Ç·Î ¿¹¿Ü¸¦ ¹ß»ýÇÒ ¼ö¹Û¿¡ ¾ø´Ù. ´ÙÀ½ ¿¹Á¦·Î ÀÌ ¿¬»êÀÚÀÇ µ¿ÀÛÀ» Àß °üÂûÇØ º¸ÀÚ. typeid ¿¬»êÀÚ¸¦ »ç¿ëÇÏ·Á¸é typeinfo Çì´õ ÆÄÀÏÀ» Æ÷ÇÔÇØ¾ß ÇÏ¸ç ¶ÇÇÑ ÇÁ·ÎÁ§Æ® ¼³Á¤ ´ëÈ»óÀÚ¿¡¼ RTTI ¿É¼Çµµ ¼±ÅÃÇØ¾ß ÇÑ´Ù.
¿¹ Á¦ : typeid |
#include <Turboc.h>
#include <typeinfo>
class Parent
{
public:
virtual void PrintMe() { printf("I am Parent\n"); }
};
class Child : public Parent
{
private:
int num;
public:
Child(int anum=1234) : num(anum) { }
virtual void PrintMe() { printf("I am Child\n"); }
void PrintNum() { printf("Hello Child=%d\n",num); }
};
void main()
{
Parent P,*pP;
Child C,*pC;
pP=&P;
pC=&C;
printf("P=%s, pP=%s, *pP=%s\n",
typeid(P).name(),typeid(pP).name(),typeid(*pP).name());
printf("C=%s, pC=%s, *pC=%s\n",
typeid(C).name(),typeid(pC).name(),typeid(*pC).name());
pP=&C;
printf("pP=%s, *pP=%s\n",
typeid(pP).name(),typeid(*pP).name());
}
main¿¡¼ °´Ã¼ P¿Í C ±×¸®°í °¢ ŸÀÔÀÇ Æ÷ÀÎÅÍ pP¿Í pC¸¦ ¼±¾ðÇÏ¿© Æ÷ÀÎÅÍ°¡ °´Ã¼¸¦ °¡¸®Å°µµ·Ï Çß´Ù. Æ÷ÀÎÅÍ¿Í °´Ã¼ÀÇ ÂüÁ¶ °ü°è¸¦ ±×¸²À¸·Î ±×·Á º¸¸é ´ÙÀ½°ú °°´Ù.
ÀÌ »óÅ¿¡¼ typeid·Î °´Ã¼, Æ÷ÀÎÅÍ, ±×¸®°í Æ÷ÀÎÅÍ°¡ °¡¸®Å°´Â ´ë»óüÀÇ Å¸ÀÔÀ» Á¶»çÇÏ¿© À̸§À» Ãâ·ÂÇß´Ù. ´ÙÀ½Àº ºñÁÖ¾ó C++ÀÇ ½ÇÇà °á°úÀÌ´Ù.
P=class Parent, pP=class Parent *, *pP=class Parent
C=class Child, pC=class Child *, *pC=class Child
pP=class Parent *, *pP=class Child
Ŭ·¡½ºÀÇ À̸§À» Ç¥ÇöÇÏ´Â ¹æ½Äµµ ÄÄÆÄÀÏ·¯¸¶´Ù ´Ù¸¦ ¼ö Àִµ¥ ºñÁÖ¾ó C++Àº Ŭ·¡½ºÀÏ ¶§ class¶ó´Â ´Ü¾î¿Í Ŭ·¡½º À̸§À¸·Î Ç¥½ÃÇÏ°í Æ÷ÀÎÅÍ´Â µÚ¿¡ *¸¦ ´õ ºÙÀδÙ. ´ÙÀ½Àº gccÀÇ ½ÇÇà °á°úÀε¥ ºñÁÖ¾ó C++°ú´Â ´Ù¸¥ À̸§À» »ç¿ëÇÑ´Ù.
P=6Parent, pP=P6Parent, *pP=6Parent
C=5Child, pC=P5Child, *pC=5Child
pP=P6Parent, *pP=5Child
¾Õ µÎ ÁÙÀÇ °á°ú´Â ¾ÆÁÖ ´ç¿¬ÇÏ°í »ó½ÄÀûÀÌ´Ù. Parent ŸÀÔÀÇ P³ª Æ÷ÀÎÅÍ Å¸ÀÔÀÇ pP³ª pP°¡ °¡¸®Å°´Â ´ë»óü´Â ¸ðµÎ Parent Ŭ·¡½º ŸÀÔÀ̸ç ChildÀÇ °æ¿ìµµ ¸¶Âù°¡Áö´Ù. ±×·¯³ª ¸¶Áö¸· ÁÙÀÇ °á°ú´Â Á¶±Ý ´Ù¸£´Ù. Parent ŸÀÔÀÇ Æ÷ÀÎÅÍ pP´Â ÆÄ»ý °´Ã¼ÀÎ CÀÇ ¹øÁö¸¦ ´ëÀÔ¹ÞÀ» ¼ö Àִµ¥ ÀÌ »óÅ¿¡¼ pPÀÇ Å¸ÀÔ°ú *pPÀÇ Å¸ÀÔÀÌ °¢°¢ ´Ù¸£°Ô ³ªÅ¸³´Ù. pP´Â Æ÷ÀÎÅÍ ÀÚüÀÇ Å¸ÀÔÀ» ¹°Àº °ÍÀ̹ǷΠParent *¶ó´Â °á°ú°¡ ³ª¿À°í pP°¡ ÇöÀç Child ŸÀÔÀ» °¡¸®Å°°í ÀÖÀ¸¹Ç·Î *pP´Â Child¶ó´Â °á°ú°¡ ³ª¿Â´Ù. ºÎ¸ð ŸÀÔÀÇ Æ÷ÀÎÅÍ°¡ ÀÚ½Ä °´Á¦¸¦ °¡¸®Å°°í ÀÖÀ½À» ÀνÄÇÑ´Ù´Â ¾ê±âÀÌ´Ù.
°¢ °´Ã¼¿Í Ŭ·¡½º¿¡ ŸÀÔ¿¡ ´ëÇÑ Á¤º¸°¡ ¾ø´Ù¸é pP°¡ Á¤È®ÇÏ°Ô ´©±¸¸¦ °¡¸®Å°´ÂÁö¸¦ ¾Æ´Â °ÍÀº ºÒ°¡´ÉÇϸç RTTI¿¡ ÀÇÇØ ÀÌ·± Á¤º¸°¡ À¯ÁöµÇ°í Á¶»çµÇ´Â °ÍÀÌ´Ù. ½ÇÇàÁß¿¡ Æ÷ÀÎÅÍ°¡ ´©±¸¸¦ °¡¸®Å°´ÂÁö¸¦ Á¤È®ÇÏ°Ô ¾Ë ¼ö ÀÖ°Ô µÇ¾úÀ¸¹Ç·Î ¾ÕÀÇ ¿¹Á¦¿¡¼ func ÇÔ¼ö¸¦ RTTI¸¦ »ç¿ëÇØ ¼öÁ¤ÇØ º¸ÀÚ. ÀÌ ¿¹Á¦µµ Á¦´ë·Î ÄÄÆÄÀÏÇÏ·Á¸é typeinfo Çì´õ¸¦ Æ÷ÇÔÇÏ°í RTTI ¿É¼ÇÀ» ÄÑ¾ß ÇÑ´Ù.
#include <typeinfo>
....
void func(Parent *p)
{
p->PrintMe();
if (strcmp(typeid(*p).name(),"class Child")==0) {
((Child *)p)->PrintNum();
} else {
puts("ÀÌ °´Ã¼´Â numÀ» °¡Áö°í ÀÖÁö ¾Ê½À´Ï´Ù.");
}
}
typeid ¿¬»êÀÚ·Î p°¡ °¡¸®Å°´Â ´ë»óü, ±×·¯´Ï±î func ÇÔ¼ö·Î Àü´ÞµÈ ½ÇÀμöÀÇ Å¸ÀÔÀ» Á¶»çÇß´Ù. name ÇÔ¼ö¸¦ È£ÃâÇϸé Ŭ·¡½º À̸§ÀÌ ¸®ÅϵǴµ¥ ÀÌ ¹®ÀÚ¿ÀÌ "class Child"¶ó¸é À̶§´Â p¸¦ ¾ÈÀüÇÏ°Ô Child *·Î ij½ºÆÃÇؼ PrintNumÀ» È£ÃâÇÒ ¼ö ÀÖ´Ù. ¸¸¾à Child °´Ã¼°¡ ¾Æ´Ï¶ó¸é ¿¡·¯ ¸Þ½ÃÁö¸¦ Ãâ·ÂÇϰųª ¾Æ´Ï¸é PrintNum È£ÃâÀ» »ý·«ÇÒ ¼ö ÀÖ´Ù. ½ÇÇà °á°ú´Â ´ÙÀ½°ú °°´Ù.
I am Child
Hello Child=5
I am Parent
ÀÌ °´Ã¼´Â numÀ» °¡Áö°í ÀÖÁö ¾Ê½À´Ï´Ù.
ParentÇü °´Ã¼¸¦ ³Ñ±â¸é À̸¦ ÆǺ°ÇØ ³½´Ù´Â °ÍÀ» È®ÀÎÇÒ ¼ö ÀÖ´Ù. type_info Ŭ·¡½ºÀÇ name ¸â¹ö·Î Ŭ·¡½º À̸§À» Á¶»çÇÏ¿© ¹®ÀÚ¿À» ºñ±³Çߴµ¥ ÀÌ ¹æ¹ýÀº Á÷°üÀûÀ̱â´Â ÇÏÁö¸¸ À̽ļº¿¡ ºÒ¸®ÇÏ´Ù. ¿Ö³ÄÇϸé RTTI´Â C++ ¾ð¾îÀÇ Ç¥ÁØ ±â´ÉÀÌÁö¸¸ Ŭ·¡½º À̸§À» Ç¥½ÃÇÏ´Â ¹æ¹ýÀº ÄÄÆÄÀÏ·¯¸¶´Ù ´Ù¸¦ ¼ö Àֱ⠶§¹®ÀÌ´Ù. gcc¸¸ Çصµ ¹ú½á À̸§À» ºÙÀÌ´Â ¹æ¹ýÀÌ ´Ù¸£¹Ç·Î À§ Äڵ带 ±×´ë·Î ÄÄÆÄÀÏÇÏ¸é ºñÁÖ¾ó C++¿¡¼´Â Á¦´ë·Î ½ÇÇàµÇÁö¸¸ gcc¿¡¼´Â Ʋ¸° ºñ±³¸¦ ÇÒ °ÍÀÌ´Ù.
±×·¡¼ À̸§À» Á÷Á¢ ºñ±³ÇÏ´Â °Íº¸´Ù´Â type_info Ŭ·¡½ºÀÇ == ¿¬»êÀÚ·Î ¿øÇϴ Ŭ·¡½ºÀÇ Å¸ÀÔ Á¤º¸¿Í °°ÀºÁö ºñ±³ÇÏ´Â °ÍÀÌ ÈξÀ ´õ ÁÁ´Ù. == ¿¬»êÀÚ´Â À̸§À» ºÙÀÌ´Â ¹æ¹ý°ú´Â ¹«°üÇÏ°Ô µÎ ´ë»óÀÇ Å¸ÀÔÀÌ °°ÀºÁö ´Ù¸¥Áö¸¦ ºñ±³ÇϹǷΠ¿ì¸®´Â ÀÌ ¿¬»êÀÚÀÇ ºñ±³ °á°ú¸¸À» »ç¿ëÇÏ¸é µÈ´Ù. ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇØ º¸ÀÚ.
void func(Parent *p)
{
p->PrintMe();
if (typeid(*p)==typeid(Child)) {
((Child *)p)->PrintNum();
} else {
puts("ÀÌ °´Ã¼´Â numÀ» °¡Áö°í ÀÖÁö ¾Ê½À´Ï´Ù.");
}
}
*pÀÇ Å¸ÀÔ Á¤º¸¿Í Child Ŭ·¡½ºÀÇ Å¸ÀÔ Á¤º¸¸¦ ºñ±³ÇÏ¿© °°À¸¸é p°¡ ChildÇüÀÇ °´Ã¼¸¦ °¡¸®Å°´Â °ÍÀ¸·Î ÆÇ´ÜÇß´Ù. typeid ¿¬»êÀÚ´Â °´Ã¼³ª °´Ã¼ÀÇ Æ÷ÀÎÅͻӸ¸ ¾Æ´Ï¶ó Ŭ·¡½º ŸÀÔµµ Àμö·Î ¹ÞÀ» ¼ö ÀÖÀ¸¹Ç·Î ¿øÇϴ Ŭ·¡½º À̸§À» ¹Ù·Î ¾µ ¼ö ÀÖ´Ù. ÀÌ ¿Ü¿¡ RTTI¿Í °ü·ÃµÈ ±â´ÉÀ¸·Î ´ÙÀ½ ÀýÀÇ dynamic_cast ¿¬»êÀÚ°¡ ÀÖ´Ù.