Array Trouble

Programming, for all ages and all languages.
Post Reply
Kon-Tiki

Array Trouble

Post by Kon-Tiki »

Ok, I've got one class and three classes that inherit from that first one. I need to have a double array that contains a combination of those three classes. An example:

class upper
class low : public upper
class lower : public upper
class lowest : public upper

array[1][5] is class low
array[2][2] is class lowest
array[5][3] is class low
array[9][6] is class lower
etc

Anybody got any idea how to do this?
Ushma

Re:Array Trouble

Post by Ushma »

An array of pointers?
Kon-Tiki

Re:Array Trouble

Post by Kon-Tiki »

How would I go about using that?
troflip

Re:Array Trouble

Post by troflip »

upper *array[10][7];

array[1][5] = new low();
array[2][2] = new lowest();
array[5][3] = new low();
array[9][6] = new lower();

// then delete when you're finished.

Of course, whomever is using the array won't know what class each element is, other than it's at least "upper".
Kon-Tiki

Re:Array Trouble

Post by Kon-Tiki »

Did that, but the compiler whines 'bout those objects not knowing the functions I call (unless the object's from class upper)
Joel (not logged in)

Re:Array Trouble

Post by Joel (not logged in) »

If you're calling functions that do not exist in upper, then you will need to use a dynamic_cast to change it into a pointer to the interface you are looking for.

You need to make sure you test the result (dynamic_cast returns null if the cast won't work), and a lot of this kind of casting may mean that you need to rethink your interface -- can what you're trying to do be accomplished by putting some virtual function in upper?
Kon-Tiki

Re:Array Trouble

Post by Kon-Tiki »

Ehmm... what's the difference between virtual function and a normal class function? And how can I use dynamic_cast?
Joel (not logged in)

Re:Array Trouble

Post by Joel (not logged in) »

Code: Select all

class upper
{
public:
    virtual void doSomething()
    {
        std::cout << "upper::doSomething" << std::endl;
    }
};

class lower : public upper
{
public:
    virtual void doSomething()
    {
        std::cout << "lower::doSomething" << std::endl;
    }
};

void someFunction(upper* pUpper)
{
    pUpper->doSomething();
}

int main()
{
    upper upperObject;
    lower lowerObject;

    someFunction(&upperObject);
    someFunction(&lowerObject);
}
The code above will print:

Code: Select all

upper::doSomething
lower::doSomething
Even though someFunction receives an upper pointer, in the second call to someFunction it "knows" that the object is really a lower so it calls lower's version of doSomething.

You use dynamic_cast like this (I believe -- this kind of thing is more common in Java than in C++):

Code: Select all

void someFunction(upper* pUpper)
{
    if (dynamic_cast<lower*>(pUpper) != NULL)
    {
        lower* pLower = dynamic_cast<lower*>(pUpper);
    }
    else if (dynamic_cast<low*>(pUpper) != NULL)
    {
        low* pLow = dynamic_cast<low*>(pUpper);
    }
}
Kon-Tiki

Re:Array Trouble

Post by Kon-Tiki »

The first one's rather pointless in my case. The second one doesn't want to compile, whining 'bout some token that needs to be put before )

For my case specific, you can check out the source here
troflip

Re:Array Trouble

Post by troflip »

Your link doesn't work for me.
ark

Re:Array Trouble

Post by ark »

I couldn't download your code, either. See if this program will compile:

Code: Select all

#include <iostream>

class upper
{
public:
   upper()
   {
   }

    virtual ~upper()
   {
   }
};

class lower : public upper
{
public:
   lower()
   {
   }
};

class low : public upper
{
public:
   low()
   {
   }
};

void someFunction(upper* pUpper)
{
   if (dynamic_cast<lower*>(pUpper) != NULL)
   {
      std::cout << "Got a lower object in someFunction" << std::endl;
   }
   else if (dynamic_cast<low*>(pUpper) != NULL)
   {
      std::cout << "Got a low object in someFunction" << std::endl;
   }
   else
   {
      std::cout << "Got neither a lower nor a low in someFunction" << std::endl;
   }
}

int main()
{
   upper upperObject;
   lower lowerObject;
   low   lowObject;

   someFunction(&upperObject);
   someFunction(&lowObject);
   someFunction(&lowerObject);

   return 0;
}
I have confirmed that this code does compile and run as expected using g++, printing:

Code: Select all

Got neither a lower nor a low in someFunction
Got a low object in someFunction
Got a lower object in someFunction
As for the virtual functions, it's almost always better to use polymorphic types than it is to downcast a pointer, if you can at all avoid it (sometimes you can't). Since I don't know what exactly you're trying to do I can't say anything more useful than that.
troflip

Re:Array Trouble

Post by troflip »

I was just trying something similar myself. I don't use these casting operators very much, but I found out that to use dynamic_cast, your compiler needs to support RTTI (run-time type information). It might be an option you can specify when compiling.
Otherwise, downcasts (casting from a base class to a derived class) won't work, because it isn't known at runtime what class it really is.
Joel (not logged in)

Re:Array Trouble

Post by Joel (not logged in) »

You can still do it (at the very least you could reinterpret_cast), but it gets uglier if you don't use RTTI. You have to roll your own method of figuring out which class it really is, such as having a "type" member in the base class, which you look at and then cast from there, but that's like a capital offense in OO circles (not that downcasting itself is exactly smiled upon, either).
Kon-Tiki

Re:Array Trouble

Post by Kon-Tiki »

Friend of mine took a look at my code, wrote a quick example of virtual functions and guided me through using them. I now understand how to use them, and it works like a charm now :) Next step's reading levels from a file and setting them up on the screen. It'd be alot easier if I wasn't forced to use the Allegro filehandling functions, as those're horribly documented and I don't know how to read a file line per line, interprete each character from it and act upon that with those functions >_>
Post Reply