Using the maps
The goal of this article is to demonstrate using one of the STL�s associative containers � the map. The associative containers link a key with a value, allowing the value to be found given its key. The most powerful of the associative containers are map and multimap. These allow both the key and value to be of differing and arbitrary data types. The difference between map and multimap is that map requires unique keys and multimap does not.
Therefore, the map class supports an associative container in which unique keys are mapped with values. In essence, a key is simply a name that you give to a value. Once a value has been stored, you can retrieve it by using its key. Thus, in its most general sense a map is a list of key/value pairs. The power of a map is that you can look up a value given its key.
The template specification for map is shown here:
template <class Key, class T, class Comp = less<Key>, class Allocator = allocator<T> class map
Here, Key is the data type of the keys, T is the data type of the values being stored (mapped), and Comp is a function that compares two keys.
As illustration, I�m going to give one relatively simple example with following class hierarchy:
class Employee
{
�
};
class Employees
{
virtual bool InitData() = 0;
public:
Employee employee;
virtual bool AddToEmployees( Employee new_employee ) = 0;
virtual bool RemoveFromEmployees( string ssn ) = 0;
virtual bool FindEmployee( string ssn, Employee &employee_found ) = 0;
};
class MyCompanyEmployees : public Employees
{
EmployeeMap theMap;
EmployeeMap::iterator theIterator;
bool InitData();
public:
MyCompanyEmployees();
~MyCompanyEmployees();
bool AddToEmployees( Employee new_employee );
bool RemoveFromEmployees( string ssn );
bool FindEmployee( string ssn, Employee &employee_found );
STRING_VECTOR GetData( Employee employee );
};
In my test application I use one modificated class String Tokenizer too.
This is pure C++ driver program and main function seems like this:
#include <iostream>
#include "MyCompanyEmployees.h"
typedef vector<string> STRING_VECTOR;
int main( void )
{
string ssn;
Employee emp;
MyCompanyEmployees MyCompany;
STRING_VECTOR employee_data;
STRING_VECTOR::iterator employee_data_iterator;
char input;
cout << "DEMONSTRATION PROGRAM - EMPLOYEE" << endl;
while( 1 )
{
cout << "Enter add(a), remove(r), find(f), quit(q): ";
cin >> input;
switch( input )
{
case 'a':
{
string ssn, first_name, last_name, marital_status, home_address, home_phone_number,
office_phone_number, salary, title;
cout << endl << "Enter SSN: ";
cin >> ssn;
cout << "Enter first name: ";
cin >> first_name;
cout << "Enter last name: ";
cin >> last_name;
cout << "Enter marital status: ";
cin >> marital_status;
cout << "Enter home address: ";
cin >> home_address;
cout << "Enter home phone number: ";
cin >> home_phone_number;
cout << "Enter office phone number: ";
cin >> office_phone_number;
cout << "Enter salary: ";
cin >> salary;
cout << "Enter title: ";
cin >> title;
emp.SetSSN( ssn );
emp.SetFirstName( first_name );
emp.SetLastName( last_name );
emp.SetMaritalStatus( marital_status );
emp.SetHomeAddress( home_address );
emp.SetHomePhoneNumber( home_phone_number );
emp.SetOfficePhoneNumber( office_phone_number );
emp.SetSalary( salary );
emp.SetTitle( title );
if( MyCompany.AddToEmployees( emp ) )
cout << "Insertion occured...\n";
else
cout << "Duplicate not allowed...\n";
}
continue;
case 'r':
{
cout << "Enter SSN that you want to remove: ";
cin >> ssn;
if( !MyCompany.RemoveFromEmployees( ssn ) )
cout << "Error while removing..." << endl;
else
cout << "Removing occured..." << endl;
}
continue;
case 'f':
{
cout << "Enter SSN that you want to find: ";
cin >> ssn;
if( MyCompany.FindEmployee( ssn, emp ) )
{
employee_data = MyCompany.GetData( emp );
for( employee_data_iterator = employee_data.begin(); employee_data_iterator != employee_data.end(); employee_data_iterator++ )
{
cout << *employee_data_iterator;
if( employee_data_iterator != employee_data.end() - 1 )
cout << ", ";
}
cout << endl;
}
else
cout << "Name not in directory...\n";
}
continue;
case 'q':
cout << "Quit\n";
exit( 0 );
default:
cout << "Error: Bad command " << input << '\n';
break;
}
}
return 0;
}
Like data source you have one simple text (parsing_file.txt) file which is filled with four lines of data:
1111,John,Johnson,yes,Street1,(416)111-1111,(416)101-1010,50000,Manager
2222,Adam,Smith,yes,Street2,(416)222-2222,(416)202-2020,35000,Technician
3333,Bob,Fitzgerald,no,Street3,(416)333-3333,(416)303-3030,45000,Programmer
4444,James,Sulivan,no,Street4,(416)444-4444,(416)404-4040,40000,Teacher
The first column represents, at the same time, the key in our map, so that if you want to find or remove some data from map you should type only the number: 1111 or 2222 or�
This example could be more useful because we have storing the class object in a map.