Конструкторы и деструкторы. Конструкторы и деструкторы по умолчанию
описаны следующим образом:
MPI::<CLASS>()
~MPI::<CLASS>()
В терминах конструкторов и деструкторов, явные объекты MPI уровня пользователя ведут себя как дескрипторы. Конструкторы по умолчанию для всех объектов кроме MPI::Status создают соответствующие дескрипторы MPI::*_NULL. То есть, когда создан экземпляр объекта MPI, сравнение его с соответствующим объектом MPI::*_NULL даст положительный результат. Конструкторы по умолчанию не создают новых явных объектов MPI. Некоторые классы для этого имеют в своем составе функцию Create().
Пример 8.2 В этом фрагменте проверка даст истинный результат и на
cout будет выведено сообщение:
void foo()
{
MPI::Intracomm bar;
if (bar == MPI::COMM_NULL)
cout << "bar is MPI::COMM_NULL" << endl;
}
Деструктор для каждого объекта MPI уровня пользователя не вызывает соответствующую функцию MPI_*_FREE (если она существует).
Объяснение: Функции MPI_*_FREE не вызываются автоматически в следующих случаях:
void example_function()
{
MPI::Intracomm foo_comm(MPI::COMM_WORLD), bar_comm;
bar_comm = MPI::COMM_WORLD.Dup();
// остальной код функции
}
Копирование и присваивание.
Конструктор копирования и оператор присваивания описаны следующим образом:
MPI::<CLASS>(const MPI::<CLASS>& data)
MPI::<CLASS>& MPI::<CLASS>::operator=(const MPI::<CLASS>& data)
В терминах копирования и присваивания явные объекты MPI уровня пользователя работают как дескрипторы. Конструкторы копирования производят основанные на дескрипторах копии. Объекты MPI::Status являются исключением из этого правила. Эти объекты производят полное копирование объекта для присваивания и создания копий.
Совет разработчикам: Каждый объект MPI уровня пользователя считается содержащим по значению или ссылке реализационно-зависимую информацию о состоянии. Присваивание и копирование дескрипторов MPI объектов может просто копировать такую информацию. []
Пример 8.3 Этот пример использует оператор присваивания. Здесь MPI::Intracomm::Dup() не вызывается для foo_comm. Объект foo_comm - просто псевдоним для MPI::COMM_WORLD. Но bar_comm создан вызовом функции MPI::Intracomm::Dup() и поэтому является другим видом коммуникатора, нежели foo_comm (и поэтому отличающимся от MPI::COMM_WORLD). baz_comm становится псевдонимом для bar_comm. Если дескриптор
bar_comm или baz_comm будет освобожден вызовом MPI_COMM_FREE,
он будет установлен в MPI::COMM_NULL. Состояние другого дескриптора
будет неопределенным - оно будет неверным, хотя и не обязательно установленным
в MPI::COMM_NULL.
MPI::Intracomm foo_comm, bar_comm, baz_comm;
foo_comm = MPI::COMM_WORLD;
bar_comm = MPI::COMM_WORLD.Dup();
baz_comm = bar_comm;
Сравнение. Операторы сравнения описаны следующим образом:
bool MPI::<CLASS>::operator==(const MPI::<CLASS>& data) const
bool MPI::<CLASS>::operator!=(const MPI::<CLASS>& data) const
Функция operator==() возвращает значение true только когда дескрипторы ссылаются на один и тот же внутренний объект MPI, иначе false. Оператор operator!=() возвращает булевское дополнение для оператора operator==(). Тем не менее, так как класс Status не дескриптор для объекта более низкого уровня, то нет смысла сравнивать экземпляры объекта Status. Поэтому, функции operator==() и operator!=() в этом классе не определены.
Константы. Константы это единичные объекты и объявлены они как const. Заметьте - не все глобальные объекты MPI являются константами. Например, MPI::COMM_WORLD и MPI::COMM_SELF - не объявлены как const.