我正在创建一个类来包装一些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;
}
我想知道我是否错过了一种更优雅的方式来解决这个问题,以及两者的相对优缺点。
答案 0 :(得分:1)
您应该在构造函数初始化列表
中初始化const
个成员
class A {
const int i;
A(int c) : i(c) {
....
}
};
如果需要使用复杂表达式初始化i
,则可能需要具有静态成员函数。见http://www.learncpp.com/cpp-tutorial/101-constructor-initialization-lists/
答案 1 :(得分:1)
您可以编写包装函数来初始化初始化列表中的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-correctness。