Aniss Be
Aniss Be

Reputation: 173

How to cast array of base class pointer to derived class

How we could cast an Array of base class pointer to an array of derived class pointer. The following code show an simple example of what i'am trying to do :

class CBaseClass
{
    public :
        int CommonValue;
};

class CFirstItem : public CBaseClass
{
    public :
        int firtValue;      
};

class CSecondItem : public CBaseClass
{
    public :
        int secondValue;        
};

class CThirdItem : public CBaseClass
{
    public :
        int thirdValue;     
};


class Manager
{
    public :
        Manager()
        {
            for (unsigned int index = 0; index < 5; ++index)
            {
                m_firstItem[index] = new CFirstItem();
            }
            for (unsigned int index = 0; index < 10; ++index)
            {
                m_secondItem[index] = new CSecondItem();
            }
            for (unsigned int index = 0; index < 12; ++index)
            {
                m_thirdItem[index] = new CThirdItem();
            }
        }

    private :
        CBaseClass* m_firstItem[5];
        CBaseClass* m_secondItem[10];   
        CBaseClass* m_thirdItem[12];    
};

My main question here is how could i cast from CBaseClass to an CFirstClass or CSecondClass, i tried

CFirstClass* wFirstClass = static_cast<wFirstClass*>(m_firstItem);

And that doesn't seems to work, there is any way to how this cast should be made ?

Upvotes: 1

Views: 1833

Answers (2)

R Sahu
R Sahu

Reputation: 206607

CFirstClass* wFirstClass = static_cast<wFirstClass*>(m_firstItem);

is wrong since w_firstItem decays to CBaseClass** in the above expression.

You will be better off if you can design your program such that you don't need to cast. If you must cast, you will need to use dynamic_cast.

CFirstClass* wFirstClass = dynamic_cast<CFirstClass*>(m_firstItem[0]);
if ( wFirstClass )
{
   // Use the pointer.
}
else
{
   // Deal with other cases
}

If you need to cast every pointer in m_firstItem, you need to use a loop.

for ( auto item : m_firstItem )
{
   CFirstClass* wFirstClass = dynamic_cast<CFirstClass*>(item);
   if ( wFirstClass )
   {
      // Use the pointer.
   }
   else
   {
      // Deal with other cases
   }
}

Update

@RemyLebeau makes a good point. You should use dynamic_cast only if m_firstItem holds pointers to different sub-types of CBaseClass. In your posted code, since it holds only pointers to CFirstClass, it's ok to use static_cast instead of dynamic_cast:

CFirstClass* wFirstClass = static_cast<CFirstClass*>(m_firstItem[0]);

The loop version can similarly use static_cast<CFirstClass*>(item).

Upvotes: 3

Remy Lebeau
Remy Lebeau

Reputation: 596497

You can't simply type-cast an array of base pointers to an array of derived pointers. The pointers will not be pointing at the correct addresses. If you need an array of derived pointers, you have to create a separate array and type-cast the source items correctly, eg:

CFirstClass* wFirstClass[5];
for (int i = 0; i < 5; ++i)
    wFirstClass[i] = static_cast<CFirstClass*>(m_firstItem[i]);

Same with the other arrays:

CSecondClass* wSecondClass[10];
for (int i = 0; i < 10; ++i)
    wSecondClass[i] = static_cast<CSecondClass*>(m_secondItem[i]);

CThirdClass* wThirdClass[12];
for (int i = 0; i < 12; ++i)
    wThirdClass[i] = static_cast<CThirdClass*>(m_thirdItem[i]);

Upvotes: 2

Related Questions