Search code examples
c++oopvisual-c++containment

Accessing Members of Containing Objects from Contained Objects


If I have several levels of object containment (one object defines and instantiates another object which define and instantiate another object..), is it possible to get access to upper, containing - object variables and functions, please?

Example:

    class CObjectOne
    {
    public:
       CObjectOne::CObjectOne() { Create(); };

       void Create();

       std::vector<ObjectTwo>vObejctsTwo;
       int nVariableOne;
    }
    bool CObjectOne::Create()
    {
       CObjectTwo ObjectTwo(this);
       vObjectsTwo.push_back(ObjectTwo);
    }

    class CObjectTwo
    {
     public:
       CObjectTwo::CObjectTwo(CObjectOne* pObject)
       {
        pObjectOne = pObject;
        Create();
       };

       void Create();
       CObjectOne* GetObjectOne(){return pObjectOne;};

       std::vector<CObjectTrhee>vObjectsTrhee;
       CObjectOne* pObjectOne;
       int nVariableTwo;
    }
    bool CObjectTwo::Create()
    {
       CObjectThree ObjectThree(this);
       vObjectsThree.push_back(ObjectThree);
    }

    class CObjectThree
    {
     public:
       CObjectThree::CObjectThree(CObjectTwo* pObject)
       {
        pObjectTwo = pObject;
        Create();
       };

       void Create();
       CObjectTwo* GetObjectTwo(){return pObjectTwo;};

       std::vector<CObjectsFour>vObjectsFour;
       CObjectTwo* pObjectTwo;
       int nVariableThree;
    }
    bool CObjectThree::Create()
    {
       CObjectFour ObjectFour(this);
       vObjectsFour.push_back(ObjectFour);
    }

main()
{
    CObjectOne myObject1;
}

Say, that from within CObjectThree I need to access nVariableOne in CObjectOne. I would like to do it as follows:

int nValue = vObjectThree[index].GetObjectTwo()->GetObjectOne()->nVariable1;

However, after compiling and running my application, I get Memory Access Violation error.

  • What is wrong with the code above(it is example, and might contain spelling mistakes)?
  • Do I have to create the objects dynamically instead of statically?
  • Is there any other way how to achieve variables stored in containing objects from withing contained objects?

Solution

  • When you pass a pointer that points back to the container object, this pointer is sometimes called a back pointer. I see this technique being used all the time in GUI libraries where a widget might want access to its parent widget.

    That being said, you should ask yourself if there's a better design that doesn't involve circular dependencies (circular in the sense that the container depends on the containee and the containee depends on the container).

    You don't strictly have to create the objects dynamically for the back pointer technique to work. You can always take the address of a stack-allocated (or statically-allocated) object. As long as the life of that object persists while others are using pointers to it. But in practice, this technique is usually used with dynamically-created objects.

    Note that you might also be able to use a back-reference instead of a back-pointer.


    I think I know what's causing your segmentation faults. When your vectors reallocate their memory (as the result of growing to a larger size), the addresses of the old vector elements become invalid. But the children (and grand-children) of these objects still hold the old addresses in their back-pointers!

    For the back-pointer thing to work, you'll have to allocate each object dynamically and store their pointers in the vectors. This will make memory management a lot more messy, so you might want to use smart pointers or boost::ptr_containers.


    After seeing the comment you made in another answer, I now have a better idea of what you're trying to accomplish. You should research generic tree structures and the composite pattern. The composite pattern is usually what's used in the widget example I cited previously.