RTTI ±¸Çö

1. °¡Àå °£´ÜÇÑ ¹æ½Ä

Àá±ñ define ¼±¾ð½Ã #, ##  »ç¿ë¿¡ ´ëÇؼ­ ¾Ë¾Æº¸ÀÚ

# ¼±¾ðÀº?
º¯¼ö·Î ³Ñ¾î¿Â °ªÀ» ¹®ÀÚ¿­·Î ¹Ù²Û´Ù.

#define  XSTR(s)    #s
char*  str = XSTR(test)     ¸í·ÉÀº ¾Æ·¡¿Í °°´Ù.
char*  str = "test"

## ¼±¾ðÀº?
º¯¼ö·Î ³Ñ¾î¿Â °ªÀ» º¯¼ö·Î Ãë±ÞÇÑ´Ù.

#define VAR_VAR(a, b)   a##b
char*  VAR_VAR(s, tr) = XSTR(test)    ¸í·ÉÀº ¾Æ·¡¿Í °°´Ù.
char* str

RTTI ±¸ÇöÀ» ¹®ÀÚ¿­À» ÀÌ¿ëÇؼ­ ±¸ÇöÇÑ ¹æ¹ýÀÌ´Ù.
¹®ÀÚ¿­À» »ç¿ëÇÏ´Â ¹æ¹ýÀº ±¸ÇöÀº °£´ÜÇÏÁö¸¸, ¹®ÀÚ¿­À» ºñ±³ ÇÒ ¶§, ¾à°£ ´À¸®´Ù´Â ´ÜÁ¡ÀÌ ÀÖ´Ù.
½ÇÁ¦ »ç¿ëÀº  ¾Æ·¡¿Í °°ÀÌ ¼±¾ðÇÏ°í, GetClassName() ¸Þ½îµå¸¦ ½ÇÇàÇÏ¸é °¢ Ŭ·¡½ºÀÇ À̸§À» ¹ÝȯÇÑ´Ù.

¼±¾ð

#define DECLARE_RTTI(name)  \
    public:  \
    virtual const char * GetClassName()  const {  return #name; }


Á¤ÀÇ

class VECTOR
{
    DECLARE_RTTI(VECTOR);


½ÇÇà

VECTOR  vector;
char* szClassName = vector.GetClassName();    
//Ŭ·¡½º À̸§À» ¸®ÅÏÇÑ´Ù.

 

2. Æ÷ÀÎÅ͸¦ »ç¿ëÇÏ´Â ¹æ½Ä

¹®ÀÚ¿­ ´ë½Å Ŭ·¡½ºÀÇ Á¤Àû º¯¼öÀÇ ¸Þ¸ð¸® ÁÖ¼Ò¸¦ ÀÌ¿ëÇØ Å¬·¡½º¸¦ ºñ±³ÇÏ¸é ¹®ÀÚ¿­ ¹æ½Äº¸´Ù ºü¸£´Ù.
¹®ÀÚ¿­À» ÀÌ¿ë ÇÒ ¶§´Â ¸ÅÅ©·Î¸¦ Ŭ·¡½ºÀÇ Çì´õ¿¡¸¸ ¼±¾ðÇÏ¸é µÇÁö¸¸, Æ÷ÀÎÅ͸¦ »ç¿ëÇÏ´Â ¹æ½ÄÀ»
ÀÌ¿ëÇÏ´Â °æ¿ì¿¡´Â Çì´õ ÆÄÀÏ°ú ¼Ò½º ÆÄÀÏ¿¡ °¢°¢ DECLARE_RTTI¿Í IMPLEMENT_RTTI ¸ÅÅ©¸¦¸¦ Æ÷ÇÔ½ÃÄÑ¾ß ÇÑ´Ù.

Ŭ·¡½º¸¦ ºñ±³ÇÏ´Â °æ¿ì¿¡´Â SAME_RTTI ¸ÅÅ©·Î¸¦ »ç¿ëÇÑ´Ù.

¼±¾ð

#define DECLARE_RTTI   \
    public: \
    static  const    CRTTI  m_rtti; \
    virtual const    CRTTI & GetRTTI() const    {   return m_rtti; }

#define IMPLEMENT_RTTI(name)        \
     const CRTTI name::m_rtti(#name);

#define SAME_RTTI(a, b)   (&(a).GetRTTI() == &(b).GetRTTI())

//RTTI Ŭ·¡½º
class CRTTI
{
public:
    CRTTI(const std::string &name)  : m_className(name)  {};
    const   std::string & GetClassName()  const  { return m_className; }

private:
    std::string  m_className;
};


Á¤ÀÇ

//Çì´õ ÆÄÀÏ¿¡ Ãß°¡
class VECTOR
{
    DECLARE_RTTI;

//¼Ò½º ÆÄÀÏ¿¡ Ãß°¡
IMPLEMENT_RTTI(VECTOR);


½ÇÇà

    if(SAME_RTTI( lhs, rhs ))
        cout << "°°Àº Ŭ·¡½º" << endl;

 

 

3. »ó¼Ó °ü°è Ãß°¡

Æ÷ÀÎÅ͸¦ ÀÌ¿ëÇÏ´Â ¹æ½ÄÀº ¾î¶² Ŭ·¡½º¸¦ »ç¿ëÇÏ´ÂÁö ¾Ë ¼ö´Â ÀÖÁö¸¸ »ó¼Ó °ü°è¿¡ ´ëÇؼ­´Â ¾Ë¼ö´Â ¾ø´Ù.
 Æ÷ÀÎÅ͸¦ ÀÌ¿ëÇÏ´Â ¹æ½Ä¿¡ »ó¼Ó °ü°è¿¡ ´ëÇؼ­ ¾Ë±â À§ÇØ ¾à°£ ¼öÁ¤ÇÏ¿´´Ù

¿¹Á¦ ÄÚµå´Â derived_rtti_test.zip ÆÄÀÏ¿¡ ÀÖ´Ù. Äڵ尡 ª±â ¶§¹®¿¡ ºÐ¼®ÀÌ ±×·¸°Ô ¾î·ÆÁö ¾ÊÀ» °ÍÀÌ´Ù.

»ó¼Ó °ü°è¸¦ °í·ÁÇÏÁö ¾ÊÀ» ¶§´Â IMPLEMENT_RTTI ¸ÅÅ©·Î Çϳª¸é m_rtti ÃʱâÈ­°¡ °¡´ÉÇßÁö¸¸ »ó¼Ó °ü°è¸¦ ³ªÅ¸³»±â À§ÇØ IMPLEMENTBASE_RTTI ¸ÅÅ©·Î°¡ Ãß°¡ µÇ¾ú´Ù.

IMPLEMENTBASE_RTTI : º£À̽º Ŭ·¡½ºÀ϶§ »ç¿ë

IMPLEMENT_RTTI : »ó¼Ó ¹ÞÀº Ŭ·¡½º ÀÏ °æ¿ì »ç¿ë

»ó¼Ó Àû¿ë ÀÌÈÄ ¼Ò½º°¡ ¾à°£ ±æ¾îÁ®, rtti.h, rtti.cpp ÆÄÀÏ·Î ºÐ¸® ÇÏ¿´´Ù.

¼±¾ð

class CCar
{
    DECLARE_RTTI;
public:
    void Show() {   std::cout << "This is Car." << std::endl;  }
};

class CTaxi : CCar
{
    DECLARE_RTTI;
public:
    void Show() {   std::cout << "This is Taxi." << std::endl;  }
};


Á¤ÀÇ

//CTaxi´Â CCar¸¦ »ó¼Ó ¹Þ¾Ò´Ù. (¼Ò½ºÆÄÀÏ¿¡ Ãß°¡)
IMPLEMENTBASE_RTTI(CCar);
IMPLEMENT_RTTI(CTaxi, CCar);


½ÇÇà

    CTaxi    taxi;

    if (DERIVED_RTTI(CCar, taxi))
        std::cout << "taxi Derived from CCar" << std::endl;

 

3. ´ÙÁß »ó¼ÓÀÇ °æ¿ì

´ÙÁß »ó¼ÓÀÇ °æ¿ì ºÎ¸ð Ŭ·¡½º°¡ 2°³ ÀÌ»óÀ̱⠶§¹®¿¡ m_pParentRTTI¿¡ ¿©·¯°³ÀÇ Æ÷ÀÎÅ͸¦ ÀúÀå ÇÒ ¼ö ÀÖµµ·Ï ÀÌÁßÆ÷ÀÎÅÍ(**)·Î ó¸®ÇÑ´Ù.

»ý¼ºÀÚ¿¡ ºÎ¸ðŬ·¡½ºÀÇ CRTTI¸¦ ¿©·¯°³ ³Ñ±â±â À§Çؼ­. °¡º¯ ÀÎÀÚ ¸®½ºÆ®¸¦ »ç¿ëÇÑ´Ù.
°¡º¯ ÀÎÀÚ´Â ¸ÅÅ©·Î·Î ¸¸µé±â Èûµé´Ù. ±×·¡¼­ Á÷Á¢ ÀÔ·ÂÇÑ´Ù.

Ãß°¡µÈ °Í:

CRTTI(const std::string &name, int numParents, ...);
~CRTTI();

CRTTI::CRTTI(const std::string &name, int numParent, ...) : m_className(name)
{
    if (numParent < 1)
    {
        m_numParent = 0;
        m_pParentRTTI  = NULL;
    }
    else
    {
        m_numParent = numParent;
        m_pParentRTTI = new const CRTTI*[m_numParent];

        va_list v;
        va_start(v, numParent);
        for (int i=0; i < m_numParent; ++i)
        {
            m_pParentRTTI[i] = va_arg(v, const CRTTI*);
        }
        va_end(v);
    }
}

CRTTI::~CRTTI()
{
    delete [] m_pParentRTTI;
}

¼öÁ¤µÈ °Í:

2°³ ÀÌ»óÀÇ ºÎ¸ð Ŭ·¡½º¸¦ ÀúÀåÇϱâ À§ÇØ CRTTI* m_pParentRTTI     ---> CRTTI ** m_pParentRTTI ·Î ¼öÁ¤   

bool DerivedFrom (const CRTTI & rtti) const

bool    CRTTI::DerivedFrom (const CRTTI & rtti) const
{
    const CRTTI * pCompare = this;
    if (pCompare == &rtti)
        return true; 

    for (int i=0; i < m_numParent; ++i)
    {
        if (m_pParentRTTI[i]->DerivedFrom(rtti))
            return true;
    } 

    return false;
}

 

¼±¾ð

class CAirplane
{
    DECLARE_RTTI;

public:
    void Show() {  std::cout << "This is Airplane." << std::endl;  }
};

class CTaxi : CCar, CAirplane
{
    DECLARE_RTTI;

public:
    void Show() {   std::cout << "This is Taxi." << std::endl;  }
}


Á¤ÀÇ

IMPLEMENTBASE_RTTI(CAirplane);
//´ÙÁß »ó¼ÓÀº ¸ÅÅ©·Î¸¦ »ç¿ëÇϱâ Èûµé±â ¶§¹®¿¡ Á÷Á¢ ÀÔ·ÂÇÑ´Ù.
const CRTTI CTaxi::m_rtti ("CTaxi", 2, &CCar::m_rtti, &CAirplane::m_rtti);  
IMPLEMENT_RTTI(CBus, CCar);


½ÇÇà

    if (DERIVED_RTTI(CCar, taxi))
        std::cout << "taxi Derived from CCar" << std::endl;
    if (DERIVED_RTTI(CAirplane, taxi))
        std::cout << "taxi Derived from CAirplane" << std::endl;

´ÜÀÏ »ó¼Ó¿ë CRTTI°¡ ´õ ºü¸£´Ù. ´ÙÁß »ó¼ÓÀ» ²À ÇØ¾ß ÇÏ°Ú´Ù¸é multi_rtti_test.zip ¼Ò½º¸¦ Âü°íÇÑ´Ù.
Ưº°ÇÑ °æ¿ì°¡ ¾Æ´Ï¸é, ´ÜÀÏ »ó¼ÓÀ¸·Î ÃæºÐ ÇÒ°ÍÀÌ´Ù.

Âü°í)

Á¤º¸¹®È­»ç) °ÔÀÓ ÇÁ·Î±×·¡¸Ó¸¦ À§ÇÑ C++