2

I have this [incomplete] function:

void EditorWindow::OnLMClick(SObjectType sOT, short xPos, short yPos)
{
    SObject* pSObject;

    int nElements;

    switch(sOT)
    {
        case SOT_Tile:      nElements=TILETYPE_COUNT;       pSObject = pSOTile[0];      break;
        case SOT_Surface:   nElements=SURFACEBMP_COUNT;                                 break;
        case SOT_Object:    nElements=OBJECTBMP_COUNT;                                  break;
        case SOT_Edit:      nElements=EDITBMP_COUNT;                                    break;
        default:    MessageBox(NULL,"Switch does not include this SObjectType","Error in EditorWindow::OnLMClick()",NULL); return;
    }

    // From there on, pSObject may be pointing to any array of its child classes
    for (int n = 0; n<nElements; n++)
    {
        if (xPos > pSObject->coor.X &&
            xPos < pSObject->coor.X + pSObject->size.Width &&
            yPos > pSObject->coor.Y &&
            yPos < pSObject->coor.Y + pSObject->size.Height)
        {
            selectedItemRect.left       =       pSObject->coor.X;
            selectedItemRect.top        =       pSObject->coor.Y + pSObject->size.Width;
            selectedItemRect.right      =       pSObject->coor.X;
            selectedItemRect.bottom     =       pSObject->coor.Y + pSObject->size.Height;
        }
        *(pSObject++);
    }
    Display();
}

I am trying to have pSObject point to the next element of the array pSOTile. How can I do that? Note that as I will update the function, pSObject will eventually have the possibility of pointing at other childs than just SOTile.

Mickael Bergeron Néron
  • 1,472
  • 1
  • 18
  • 31
  • I know ways that would work, but I hope there are alternatives which will be cleaner and which will result in less code. – Mickael Bergeron Néron Apr 13 '13 at 12:45
  • 2
    There is no magic way. When you cast from pointer-to-derived to pointer-to-base, you are discarding some of the type information. To move around an array, you need that information back. Cast back to the original type if you know it. Better yet, forget the pointer arithmetic and just use indices. Better still, use a standard container. If you don't know the original type, you just cannot move around the array. Use something else, e.g. a container of (smart) pointers. – n. m. could be an AI Apr 13 '13 at 13:19
  • 1
    Also see http://stackoverflow.com/a/7196224/368896 which highlights the fact that there is no "magic" way. – Dan Nissenbaum Apr 13 '13 at 13:20

1 Answers1

0

Well, maybe this isn't going to work for you, but it reminds me of iterating data structures back in school. Commonly, I would declare a class pointer member within the class. Since you want to point it at more than just CTile, I am going to assume you are using class inheritance to achieve your goal, maybe not.

class YourClass : public base {
    private:
        // Your Stuffs
    public:
        // More stuffs
}

Now, in base, declare a static vector base* pointer that you will always push_back in your constructor. Then when you want to iterate the objects, you can iterate the pointer.

class base {
    private:
        static std::vector<base*> AllMyFoos;
    //rest of your foos
}

In your .cpp don't forget to init. std::vector<base*> base::AllMyFoos; In all of your constructors that inherit base add:

MyNewClass::MyNewClass() {
    AllMyFoos.push_back(this);
    //more stuff
}

Then you can iterate and access all child functions with

//Non iter version because that stuff creeps me out
for (int i = 0; i < AllMyFoos.size(); i++ ) {
     AllMyFoos->SomeFunction() 
     //will access most derived function of SomeFunction() if you declared everything virtual.   
     //Either can be a base function or a derived function of MyNewClass.
}

I think this is how I would do it, but I couldn't simply inject that into your example code and don't know if that is possible.

Chemistpp
  • 2,006
  • 2
  • 28
  • 48