Modeling Services > Basic Features > Dictionaries > Using a Dictionary
 
Using a Dictionary
Retrieving an Object from a Dictionary
Rogue Wave® Server dictionaries include the IlsDictionary::get function, which returns the object associated with the identifier passed as its argument:
AirportP get(IlsIdentifier);
If no object is associated with the specified identifier, a null smart pointer is returned.
The member operator [] offers the same service:
AirportP operator[](IlsIdentifier);
Thus, you can write:
_dictionary["New-York"]
Adding an Object to a Dictionary
You can add an object to a dictionary by means of the insertion operator <<:
IlsDictionary<Airport>& operator<<(CAirportPR);
The smart pointer AirportP to the class Airport is added to the dictionary. If the dictionary already contains an object with the same identifier as the one specified, the exception IlsAlreadyInDictionary is thrown. For details about exceptions, see Exception Handling.
Removing an Object from the Dictionary
The member function IlsDictionary::suppress removes an object from a dictionary. This function has the following signature:
IlsDictionary<Airport>& suppress(IlsCIdentifierR);
If no object is found, the exception IlsNotFound is thrown. For details about exceptions, see Exception Handling.
Important: You should not use the suppress function in the destructor of a class for which a dictionary has been declared. Since a dictionary stores objects by means of smart pointers, the destructor of a class associated with a dictionary is invoked if the object is no longer pointed to by a smart pointer. This means that when the destructor is called, you can be sure that the object is not in the dictionary. This also means that you must explicitly remove an object from a dictionary by calling the suppress function.
Browsing Through a Dictionary
Rogue Wave Server includes an iterator of type IlsDictionary::Iterator that lets you browse through a dictionary. You initialize it with a reference to a dictionary. In the following code, the function PrintAllAirports displays the identifiers of all airports stored in the dictionary.
class Airport:
public IlsObject
{
public:
   Airport(IlsIdentifier id): identifier(id){
     _dictionary<<this;
   }
   IlsIdentifier getIdentifier(){return identifier;}
   static void PrintAllAirports();
private:
   IlsIdentifier identifier;
   static IlsDictionary<Airport> _dictionary;
};
 
void Airport::PrintAllAirports(){
   IlsDictionary<Airport>::Iterator i(_dictionary);
   AirportP airport;
   while (i>>airport)
          cout<<"Airport:"<<airport->getIdentifier()<<endl;
}
To read forward in a dictionary, you just have to use the operator >> with an iterator. This operator returns the iterator. The end of the dictionary can be recognized by converting the iterator into a Boolean ((while (i>>airport))).
The use of iterators is limited by the following two constraints:
*You cannot add new items to a dictionary when there is an iterator pointing to this dictionary. This would cause the exception IlsAddingToOpenTable to be thrown.
*You cannot remove items from a dictionary when there is an iterator pointing to this dictionary. This would cause the exception IlsRemovingFromOpenTable to be thrown. Exceptions are documented in Exception Handling.
Updating an Identifier
Dictionaries store smart pointers to objects by means of identifiers. If you modify one of these identifiers, this change must be reflected in the dictionaries that store the matching object. Failure to do so might result in dictionary inconsistencies.
The member function IlsEntity ::rename keeps dictionaries consistent whenever identifiers are updated.
The class IlsObject does not contain that member function. In Defining a Dictionary, we pointed out that the function getIdentifier had to be added to a class deriving from IlsObject if instances of this class were to be placed in a dictionary. If you want to modify the identifier of an object of type IlsObject contained in a dictionary, you must remove the object from the dictionary, change its identifier and put it back in the dictionary.
However, removing an object from the dictionary might destroy the last smart pointer referencing the object. As a consequence, it is essential to keep a smart pointer to the object in order to “hold” it (in the stack for example).
The rename function can be coded like this:
void Airport::rename(IlsIdentifier newid){
     // to avoid object deletion
     IlsSmartPointer<Airport> myself=this;
     _dictionary.suppress(getIdentifier());
     identifier=newid;
     _dictionary<<this;
}
The rename function restores the dictionary consistency. If there are several dictionaries (some of them for base classes), the code of the rename function is the following:
void Airport::rename(IlsIdentifier newid){
      // to avoid object deletion
      IlsSmartPointer<Airport> myself=this;
      _dictionary1.suppress(getIdentifier());
      _dictionary2.suppress(getIdentifier());
      //...
      identifier=newid;
      _dictionary1<<this;
      _dictionary2<<this;
      //...
}
By default, the value of the second argument passed to the IlsDictionary::suppress member function is IlsFalse. This value indicates that notification about the deletion of an object will not be carried out.

Version 6.3
Copyright © 2018, Rogue Wave Software, Inc. All Rights Reserved.