[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 517
  • Last Modified:

Getting pointer to an object stored in a map

Hi,

I have a template based map that is declared as follows :
class CMyMap : public CMap<CString, LPCTSTR, CMyObject, CMyObject&)
{
public:
      CMyMap() {};
      ~CMyMap() {};

protected:
      CMyObject *GetValuePtrFromPos(POSITION pos);
}

I stored some items in it.

Now I want to iterate through the map and get a pointer to each object
stored. The pointer has to point to the object embedded in the CAssoc
structure maintained by the map, so that it stays valid until the mapĀ“s
elements are removed.

CMyMap map;
POSITION pos=map.GetStartPosition();
while (pos != NULL)
{
   CString strKey;
   CMyObject Obj;

   CMyObject* pObj = map.GetValuePtrFromPos(pos);
   map.GetNextAssoc(pos, strKey, Obj);
   :
}

Could somebody give me some hints of how to implement GetValuePtrFromPos
and tell me what the relation is between a POSITION type variable and an
internal CAssoc structure. Every help would be very appreciated.

Thanx in advance.
0
bs161900
Asked:
bs161900
  • 3
  • 2
1 Solution
 
abk102299Commented:
I doubt it's possible the way you described. Your definition: CMap<CString, LPCTSTR, CMyObject, CMyObject&) is so called values collection. I such type of collection you have no access to CmyObject address. To use pointers you need so called pointers collection defined as follows: CMap<CString, LPCTSTR, CmyObject*, const CmyObject*>. In this case you just don't need your GetValuePtrFromPos
method any more because the GetNextAssoc method will return you a pointer to object by position. But you have to take care about your map cleanup destroying existing objects when map collection is destructed. The deletion loop may be as following:

MyMap:~MyMap()
{
            CmyObject * pObj;
            CString  key;
            for (POSITION pos = map.GetStartPosition(); pos; )
            {
                  map.GetNextAssoc( pos, key, pObj);
                  delete pObj;
            }
}
0
 
abk102299Commented:
I am sorry - a bug. For pointers collection should be:CMap<CString, LPCTSTR, CmyObject*, CmyObject*>
( remove the "const" modificatior )
0
 
bs161900Author Commented:
First of all I want to apologize for my late respons and
secondly I want to thank you for your effort in trying to
help me.

You are right saying that using a pointer collection would
be far more easy to solve my problem.
When I first began writing my application, I used object
pointers instead of objects, but I encountered some problems
when I had to compare the contents of those objects. (Using
pointers requires that you overwrite the global template function
CompareElements). Now that I am a little more familiar with the
template collections, I am considering using pointers again.

Still my question remains. Suppose I am storing bare objects
in a CMap derived collection class.
Internally, they are embedded in a CAssoc structure the framework
dynamically created. So they have an address.
I tried to implement GetValuePtrFromPos this way :

CMyObject* CMyMap::GetValuePtrFromPos(POSITION pos)
{
   return &(((CAssoc *) pos)->value);
}

But this did not work. Why ??
0
 
abk102299Commented:
As for your GetValuePtrFromPos I think the following implementation would work:

CMyObject* CMyMap::GetValuePtrFromPos(POSITION pos)
{
      CAssoc* pAssocRet = (CAssoc*)pos;
      ASSERT(pAssocRet != NULL);
      if (pAssocRet == (CAssoc*) BEFORE_START_POSITION)
      {
            // find the first association
            for (UINT nBucket = 0; nBucket < m_nHashTableSize; nBucket++)
                  if ((pAssocRet = m_pHashTable[nBucket]) != NULL)
                        break;
            ASSERT(pAssocRet != NULL);  // must find something
      }
      return &(pAssocRet->value);
}

BUT the BEFORE_START_POSITION constant here just corresponds to the FIRST value that may be different with time. Other positions just represent some addresses which also may be filled with different CMyObject objects re-associated with the KEY. In addition there are several CMap's internal implementation details used here and they may be ( not likely ) changed in later MFC versions.

As for me the pointers approach just looks more transparent.
0
 
bs161900Author Commented:
Your routine seems to work fine. It gives me a better insight in the
workings of a map.
Although I changed my map implementation so that it holds object pointers
now, and all works fine as well. Thanks for your help.
0

Featured Post

Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now