Сейчас я создаю класс, чтобы обернуть некоторые функции связи MPI, которые я создаю с помощью конкретного коммуникатора MPI. Я хотел бы, чтобы класс имел ранг и размер коммуникатора в качестве постоянных переменных-членов. К сожалению, они доступны только путем передачи указателя на int в функцию C.
class Comm {
public:
const int rank;
const int size;
Comm(MPI_Comm);
};
Comm::Comm(MPI_Comm c) {
MPI_Comm_rank(c, &rank); //error: rank is const
}
На ум приходят два подхода:
1) Наследовать от другого класса, который получает значения
class Initializer {
protected:
int hiddenSize;
int hiddenRank;
public:
Initializer(MPI_Comm);
}
class Comm : private Initializer {
public:
const int size;
const int rank;
Comm(MPI_Comm);
}
Initializer::Initializer(MPI_Comm c) {
MPI_Comm_rank(c, &hiddenRank);
MPI_Comm_size(c, &hiddenSize);
}
Comm::Comm(MPI_Comm c) : Initializer(c), rank(hiddenRank), size(hiddenSize) {}
2) Сделать членов доступными только с помощью вызовов функций
class Comm {
private:
int rank;
int size;
public:
Comm(MPI_Comm);
int getRank();
int getSize();
};
Comm::Comm(MPI_Comm c) {
MPI_Comm_rank(c, &rank);
MPI_Comm_size(c, &size);
}
int Comm::getRank() {
return rank;
}
int Comm::getSize() {
return size;
}
Интересно, пропустил ли я более изящный подход к этому, и каковы относительные достоинства и недостатки этих двух?
Вы могли бы написать функции-обертки для инициализации const
члены в списке инициализатора.
class Comm {
public:
const int rank;
const int size;
Comm(MPI_Comm) : rank(get_rank(c)), size(get_size(c)) {}
private:
static int get_rank(MPI_Comm c) {
int rank;
MPI_Comm_rank(c, &rank);
return rank;
}
// and likewise for size
};
Это было бы аккуратнее, чем раздувание объекта «скрытыми» членами, используемыми только во время строительства; и может быть лучше, чем закрытые переменные с аксессорами, так как вы можете применять const-корректность в членах класса.
Вы должны инициализировать const
члены в списке инициализатора конструктора
class A {
const int i;
A(int c) : i(c) {
....
}
};
вам может понадобиться статический функция-член, если вам нужно инициализировать i
со сложным выражением. Увидеть http://www.learncpp.com/cpp-tutorial/101-constructor-initialization-lists/