-1

Hello

I have a Container class that will allow me to store & retrieve elements from it easily by using the member variables of the elements as their key/identifier.

My problem is I am tring to store a pointer to an objects member variable, but I get a compiler error. What am I doing wrong?
PS: do you have any advice on how I could improve my Container class; such as using const correctly & whether to hide the copy constructor?

This is how I use my container class:

#include <iostream>
#include "ObjectCollection.h"

using namespace std;

// Test items
struct FoodItem
{
    unsigned int ID;
    string name;
    double price;
};

struct Order
{
    unsigned int ID; 
    unsigned int personID;   
};


int main()
{
    Collection <FoodItem*, std::string> foodCol( &FoodItem::name ); 
    Collection <Order*, unsigned int> orderCol( &Order::personID ); 
    
    // Create some test objects
    string nNames[]           = {"a", "b", "c", "d"};
    double nPrices[]          = {1.1, 2.2, 3.3, 4.4};
    unsigned int nPersonIDs[] = {6, 7, 8, 9};
    
    for (int i=0; i<4; i++)
    {
        FoodItem *f = new FoodItem() { i, nNames[i], nPrices[i] };
        Order    *o = new Order() { i, nPersonIDs[i] };
        
        foodCol.store( f );
        orderCol.store( o );
    }
    
    // Test collection
    if ( foodCol["a"]->ID == 0 ) 
    {
         cout << "Correctly retrieved a stored FoodItem by its name \n"
    }
    
    if ( foodCol[0]->name == "a" ) 
    {
         cout << "Correctly retrieved a stored FoodItem by its ID \n"
    }
    
    if ( foodCol[7]->ID == 1 ) 
    {
         cout << "Correctly retrieved a stored Order by its personID \n"
    }
    
    if ( foodCol[1]->personID == 7 ) 
    {
         cout << "Correctly retrieved a stored Order by its ID \n"
    }
    
    
    // Release dynamic memory
    for (vector <FoodItem*> f=foodCol.getValues(); !f.empty(); f.pop())
    {
        delete f.back();
    }
    
    for (vector <Order*> o=orderCol.getValues(); !o.empty(); o.pop())
    {
        delete o.back();
    }
    
    system("PAUSE");
    return 0;    
}

My Container implementation:

#ifndef OBJECTCOLLECTION
#define OBJECTCOLLECTION

#include <vector>
#include <map>

template <typename Object, typename dataType>
class Collection
{
     public:
         
         Collection( dataType Object::*nMemberVariable )
         {
             memberVariable = nMemberVariable;
         }
         
         ~Collection()
         {
                    
         } 
         
         bool store( Object* o )
         {
              // check that o is not a NULL pointer & not already present in maps
              if ( o==NULL  ||  instanceVarMap.find(o->*memberVariable) != instanceVarMap.end()  ||  instanceIntMap.find(o->ID) != instanceIntMap.end() ) 
              { 
                   return false; 
              }
              
              instanceIntMap.insert( o->ID, o );
              instanceVarMap.insert( o->*memberVariable, o ); 
              return true;
         }
         
         Object* operator[] ( dataType nParam )  // should this be a const function? I never know when to use const in functions& where not to
         {
             return get(nParam);
         }
         
         Object* operator[] ( unsigned int nParam )
         {
             return get(nParam);
         }
              
         Object* get( dataType nParam )
         {
             // do I need to check whether the element already exists or does
             // stl already do this for me?
             if ( instanceVarMap.find(nParam) == instanceVarMap.end() )
             {
                  return NULL;
             } 
             
             return instanceVarMap[ nParam ];
         }
         
         Object* get( unsigned int nParam )
         {
             if ( instanceIntMap.find(nParam) == instanceIntMap.end() )
             {
                  return NULL;
             } 
             
             return instanceIntMap[ nParam ];
         }
         
         bool remove( Object *o )
         {
             // check we have o in our collection
             if ( instanceIntMap.find(o->ID) == instanceIntMap.end() )
             {
                  return false;
             } 
             
             instanceIntMap.remove( o->ID );
             instanceVarMap.remove( o->*memberVariable );
         }
         
         int size()
         {
             return instanceIntMap.size();
         }
         
         bool empty()
         {
              return instanceIntMap.empty();
         }
         
         std::vector <Object*> getValues()
         {
             std::vector <Object*> values( instanceIntMap.size() );
             typename std::map <unsigned int, Object*>::iterator it = instanceIntMap.begin();
             
             while ( it != instanceIntMap.end() )
             {
                   values.add( (*it).second );
                   it++;
             }    
             
             return values; 
         }
         
         Object* front()
         {
             if ( instanceIntMap.empty() ) { return NULL; }
             
             typename std::map <unsigned int, Object*>::iterator it = instanceIntMap.begin(); 
             return (*it).second;
             
             // can I just say... return (*instanceIntMap.begin()).second; // even if the map is empty?
         }
         
         Object* back()
         {
             if ( instanceIntMap.empty() ) { return NULL; }
             
             typename std::map <unsigned int, Object*>::iterator it = instanceIntMap.end(); 
             it--;
             return (*it).second;
         }
            
     private:
         dataType Object::* memberVariable;
         std::map <dataType, Object*>     instanceVarMap;  // what would be more efficient; a Map or unordered_map? I heard that 
         std::map <unsigned int, Object*> instanceIntMap;  // ...unordered_maps use more memory & Maps are better when integers are the keys
                                                           // so should I use maps or unordered_maps?
         
         // I haven't really worked with handling copy constructors
         // But do you think its wise I make it private because I am storing pointers?
         Collection( const Collection &c )
         {
                     
         }
         
         Collection( Collection &c )
         {
                     
         }
         
         Collection& operator =( const Collection &c )
         {
              
         }
         
         Collection& operator =( Collection &c )
         {
              
         }

};


#endif // OBJECTCOLLECTION
2
Contributors
1
Reply
2
Views
5 Years
Discussion Span
Last Post by rubberman
This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.