Sunday, May 1, 2011

C++ polymorphic shock of passing derived object arrays into a base object pointer function parameter

Code example:

#include <cstdio>

class Mammal
{
public:
    virtual bool IsFurry() = 0;
};

class Dog : public Mammal
{
    bool isFurryBreed;
public:
    Dog() { isFurryBreed = false; }

    virtual bool IsFurry()
    {
        return isFurryBreed;
    }
};

//the line below didn't compile
//int FindFurryMammal(Mammal pMammals[], int arraySize)
int FindFurryMammal( Mammal *pMammals, int arraySize)
{
    for( int i = 0; i < arraySize; i++ )
    {
        if( pMammals[i].IsFurry() )
        {
            return i;
        }
    }
    return -1;
}

int main(int argc, char * argv[])
{
    Dog dogs[10];
    int found;

    found = FindFurryMammal(dogs, 10);

    printf("Furry mammal found at index %d\n", found);
    
    return 0;
}

The code above suffers from polymorphic shock. Indexing through pMammals would be ok if polymorphism downcasted all the indices of Dog into the Mammal base class. However, polymorphism can only cast one index at a time even if passed as a parameter to a function.
So two issues ensue where only the first index of Dog is casted to Mammal, and therefore, any indexing beyond index 0 of pMammals will result in the indexing of incorrect memory location. This results in an exception error thrown at run-time when the function IsFurry is called since that function does not exist at that memory location.

1 comment:

  1. good post Paul!

    Perhaps another post on dynamic cast, etc while we are on the topic

    ReplyDelete