2
votes

Finding the appropriate title to this question is a little difficult for me, but here is my situation. Say I have a base class and a derived class, can I pass a function that takes a parameter of type *base a type of instead *derived

class base
{
protected:
    float M_OutputValue;
    float M_InputValue;
public:
    virtual void CalculateOutput() = 0;
        /* more functions */
};

class derived: public base
{
public:
    void CalculateOutput(){ /*stuff*/};
    /* more functions */
};

And here is a function that would take the base class as an input.


void CalculateAllOutputs(base* basearray, int NumberofElements)
{
    int temp = 0;
    while(temp &lt NumberOfElements)
    {
         basearray[temp]->CalculateOutput();
         temp++;
    }
};

I'm and wondering if I can pass this function a pointer to an array of derived objects. From what I understand about casting pointer from derived to base, it is implicit and there isn't much to worry about (I looked at this question for answers). My concern is that because the derived class has more members, it takes up more bytes. That would cause the members in the array to be farther apart, so when iterating through it, a larger offset would need to be added to the memory address to get to the next element. I'm wondering if the compiler takes care of these problems so that the function I'm passing the array to knows how to access the members of the derived array. I could also solve my problem with templates of there is no solution here, but I'm trying to get better at polymorphism.

Thanks.

2

2 Answers

2
votes

You are right. Stay away from arrays, and preferably use

std::vector<std::unique_ptr<base>>

or if you don't have a C++0x-ready compiler (if this is the case, then consider upgrading), you can use

boost::ptr_vector<base>

Both are vectors of pointers which automatically clean up the pointed to objects. Avoid raw pointers, and as you point out, plain arrays simply suck.

Example of use:

void calculate_outputs(const std::vector<std::unique_ptr<base>>& b)
{
    std::for_each(b.begin(), b.end(), [](const std::unique_ptr<base>& x)
    {
        x->CalculateOutput();
    });
}
2
votes

Your concern is exactly right. Passing an array of derived would not work. If you want an array (or a vector) of polymorphic objects you are going to have to create an array of pointers. This means your function would look like this

void CalculateAllOutputs(base** basearray, int NumberofElements)
{
    int temp = 0;
    while(temp < NumberOfElements)
    {
         basearray[temp]->CalculateOutput();
         temp++;
    }
}