Reputation: 3
I'm creating a class at the moment to wrap some MPI communciation functions, which I construct with a particular MPI communicator. I'd like the class to have the rank and communicator size available as constant member variables. Unfortunately, these are only available by passing a pointer to an int into a C function.
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
}
Two approaches spring to mind to get around this:
1) Inherit from some other class that gets the values
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) Make the members accessible only by function calls
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;
}
I wonder if I've missed a more elegant way of approaching this, and what the relative merits and disadvantages are of the two.
Upvotes: 0
Views: 287
Reputation: 17455
You should initialize const
members in the constructor initializer list
class A {
const int i;
A(int c) : i(c) {
....
}
};
you may need to have a static member function if you need to initialize i
with a complex expression. See http://www.learncpp.com/cpp-tutorial/101-constructor-initialization-lists/
Upvotes: 1
Reputation: 254651
You could write wrapper functions to initialise const
members in the initialiser list.
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
};
This would be tidier than bloating the object with "hidden" members used only during construction; and might be better than private variables with accessors since you can enforce const-correctness within the class's members.
Upvotes: 1