The MPI::Comm class hierarchy makes explicit the different kinds of communicators implicitly defined by MPI and allows them to be strongly typed. Since the original design of MPI defined only one type of handle for all types of communicators, the following clarifications are provided for the C++ design.
Types of communicators There are five different types of communicators: MPI::Comm, MPI::Intercomm, MPI::Intracomm, MPI::Cartcomm, and MPI::Graphcomm. MPI::Comm is the abstract base communicator class, encapsulating the functionality common to all MPI communicators. MPI::Intercomm and MPI::Intracomm are derived from MPI::Comm. MPI::Cartcomm and MPI::Graphcomm are derived from MPI::Intracomm.
 
 
 
 Advice to users.  
Initializing a derived class with an instance of a base class is not legal in C++. For instance, it is not legal to initialize a Cartcomm from an Intracomm. Moreover, because MPI::Comm is an abstract base class, it is non-instantiable, so that it is not possible to have an object of class MPI::Comm. However, it is possible to have a reference or a pointer to an MPI::Comm.
 
 Example  
      The following code is erroneous.  
 
Intracomm intra = MPI::COMM_WORLD.Dup(); Cartcomm cart(intra); // This is erroneous( End of advice to users.)
MPI::COMM_NULL The specific type of MPI::COMM_NULL is implementation dependent. MPI::COMM_NULL must be able to be used in comparisons and initializations with all types of communicators. MPI::COMM_NULL must also be able to be passed to a function that expects a communicator argument in the parameter list (provided that MPI::COMM_NULL is an allowed value for the communicator argument).
 
 
 
 Rationale.  
 
There are several possibilities for implementation of  
   MPI::COMM_NULL.  Specifying its required behavior, rather  
  than its realization, provides maximum flexibility to implementors.  
 ( End of rationale.) 
 
 Example  
    The following example demonstrates the behavior of assignment and  
    comparison using  MPI::COMM_NULL.  
 
MPI::Intercomm comm; comm = MPI::COMM_NULL; // assign with COMM_NULL if (comm == MPI::COMM_NULL) // true cout << "comm is NULL" << endl; if (MPI::COMM_NULL == comm) // note -- a different function! cout << "comm is still NULL" << endl;
Dup() is not defined as a member function of MPI::Comm, but it is defined for the derived classes of MPI::Comm. Dup() is not virtual and it returns its OUT/ parameter by value.
MPI::Comm::Clone() The C++ language interface for MPI includes a new function Clone(). MPI::Comm::Clone() is a pure virtual function. For the derived communicator classes, Clone() behaves like Dup() except that it returns a new object by reference. The Clone() functions are prototyped as follows:
 
  
  
   Comm& Comm::Clone() const = 0 
   
   Intracomm& Intracomm::Clone() const 
   
   Intercomm& Intercomm::Clone() const 
   
   Cartcomm& Cartcomm::Clone() const 
   
   Graphcomm& Graphcomm::Clone() const 
   
 
 
 
 Rationale.  
 
 Clone() provides the ``virtual dup'' functionality that is  
  expected by C++ programmers and library writers.  Since  
   Clone() returns a new object by reference, users are  
  responsible for eventually deleting the object.  A new name is  
  introduced rather than changing the functionality of  Dup().  
 ( End of rationale.) 
 
 
 
 Advice  
        to implementors.  
 
Within their class declarations, prototypes for  Clone() and  
   Dup() would look like the following:  
 
namespace MPI { 
  class Comm { 
     virtual Comm& Clone() const = 0; 
  }; 
  class Intracomm : public Comm { 
     Intracomm Dup() const { ... }; 
     virtual Intracomm& Clone() const { ... }; 
  }; 
  class Intercomm : public Comm { 
     Intercomm Dup() const { ... }; 
     virtual Intercomm& Clone() const { ... }; 
  }; 
  // Cartcomm and Graphcomm are similarly defined 
}; 
 
Compilers that do not support the variable return type feature of  
  virtual functions may return a reference to  Comm.  Users can  
  cast to the appropriate type as necessary.  
 ( End of advice to implementors.)