33-1-³ª.typeid ¿¬»êÀÚ

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 ¿¬»êÀÚ°¡ ÀÖ´Ù.