5.3 Dereferencing the Iterator

The example above shows how to use an OEChem iterator to loop over objects, but didn't actually use them. OEChem iterators provide four operators to allow the user to access the object at the current iterator position. Implicit casting or the operator -> can be used to get a pointer to the current object, and implicit casting or the operator * can be used to get a reference to a given object. I.e. if variable iter has type OEIter<T> then (T*)iter is a pointer to the current item, and *iter and (T&)iter are of type T&. These operators mean than in most cases an OEChem iterator OEIter<T> behaves identically to a T*.

For example, to list the atomic numbers of atoms in a molecule:

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

using namespace OESystem;
using namespace OEChem;
using namespace std;

void ListAtomicNumbers(OEMolBase &mol)
{
  OEIter<OEAtomBase> atom;

  for (atom=mol.GetAtoms(); atom; ++atom)
    cout << atom->GetAtomicNum() << endl;
}

int main()
{
  OEMol mol;
  OEParseSmiles(mol, "c1ccccc1");
  ListAtomicNumbers(mol);
  return 0;
}

This routine could also be written with an explicit assignment to an OEAtomBase*.

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

using namespace OESystem;
using namespace OEChem;
using namespace std;

void ListAtomicNumbers(OEMolBase &mol)
{
  OEIter<OEAtomBase> atom;
  OEAtomBase *aptr;

  for (atom=mol.GetAtoms(); atom; ++atom)
  {
    aptr = atom;
    cout << aptr->GetAtomicNum() << endl;
  }
}

int main()
{
  OEMol mol;
  OEParseSmiles(mol, "c1ccccc1");
  ListAtomicNumbers(mol);
  return 0;
}

Comparing these two examples shows how iterators and pointers behave similarly. The OEAtomBase method, GetAtomicNum, that returns the atomic number of the given atom, will be described later.

The implicit casts of OEIter<T> to either a T& or T* are most useful when passing the object to a function which takes T by reference or by pointer.

#include "openeye.h"
#include <iostream>
#include "oeplatform.h"
#include "oesystem.h"
#include "oechem.h"

using namespace OESystem;
using namespace OEChem;
using namespace std;

void PrintAtomicNumber(const OEAtomBase *atom)
{
  cout << atom->GetAtomicNum() << endl;
}

void PrintAromatic(const OEAtomBase &atom)
{
  if(atom.IsAromatic())
    cout << "Is Aromatic" << endl;
  else
    cout << "Isn't Aromatic" << endl;
}

int main()
{
  OEMol mol;
  OEParseSmiles(mol, "c1ccccc1");

  OEIter<OEAtomBase> atom;
  for(atom = mol.GetAtoms();atom;++atom)
  {
    PrintAtomicNumber(atom);
    PrintAromatic(atom);
  }

  return 0;
}