对象数组中特定成员的和
Sum of particular members of an object array
这是我的第一个问题,所以希望这是一个好问题(我已经搜索了一个答案,但还没有找到)。
我有一个用c++编写的基于事件的疾病模型,我正试图将其转换为面向对象(部分是为了我自己的学习经验)。基本类(畜群)存储易感、感染和耐药动物的数量,以及可能发生的事件的发生率。
class Herd {
private:
int S,I,R,N;
float birth, death, infection, recovery, movement;
public:
void calc_birth(void) { birth = r*N*(1.0-N/c); }
void calc_infection(void) { infection = N>0 ? beta*S*I/N : 0.0; }
// etc.
};
然后我有一个vector
的畜群来跟踪。在整个模型中,我需要计算所有群体中每个成员的总和,在一个事件改变了群体中个体的数量或类别之后(这种情况经常发生)。我已经有4个类别和5个事件,这个模型可以很容易地扩展,需要更多。
在我的旧的过程代码中,我只是为每个成员有一个单独的向量,并且很容易创建一个sum()
函数来计算结果,但是我不知道如何在不为每个成员编写单独的sum函数的情况下使用类来做到这一点(这是可能的,但我怀疑这是一种特别好的方法)。我可以制作一个静态成员(例如sum_S
)来跟踪总数,并在每次事件发生时更新它,但这可能不适合所有成员,我不确定当涉及到比率时,总数是否可能不会慢慢偏离真实值。
是否有一种方法可以编写单个sum()
函数,该函数将我想要的成员作为参数,并返回该特定成员在所有畜群中的总和?
谢谢!
标准库头文件numeric
包含了accumulate函数。它并不完全是您想要的,但很容易适应:
#include <numeric>
#include <vector>
#include <iostream>
struct Foo {
int member;
};
int main()
{
std::vector<Foo> v = { {1}, {2}, {3} };
int sum
= std::accumulate(begin(v), end(v), 0,
// lambda that sums up
[](const int& x, const Foo& y)
{return x + y.member;});
std::cout << sum << std::endl;
return 0;
}
代码使用initializer_lists
和lambda。如果您的编译器不支持这些,请使用相应的c++ 03代码(push_back
和functors)。
当然,使用指针指向成员。
float sum_for_member( std::vector< Herd > const &herds, float Herd::*member ) {
float acc = 0;
for ( std:vector< Herd >::const_iterator it = herds.begin();
it != herds.end(); ++ it ) {
acc += (*it).*member;
}
return acc;
}
调用它:
float total_recovery = sum_for_member( my_herds, & Herd::recovery );
如果想使用成员函数getRecovery
,则形参声明为float (Herd::*member)()
,求和为acc += ((*it).*member)()
。
如果你不害怕从OO发展到泛型c++风格,你可以使用函数模板,让标准库来处理循环:
template< float Herd::*member >
float plus( float lhs, Herd const &rhs )
{ return lhs + rhs.*member; }
vector< Herd > h;
std::accumulate( h.begin(), h.end(), 0., plus< & Herd::recovery > );
所以这就是我最终得到的(在一个名为State
的类中,它包含了模拟状态,包括vector<Herd>
):
Class State {
...
template <typename T>
T sum(T (Herd::*getter)()) {
T acc = (T) 0.0;
for (int i=0; i<size; ++i) {
acc += (herds[i].*getter)();
}
return acc;
...
}
这对个体数(int
s)和事件率(float
s)都有效,并使用指向成员函数的指针来保存这些值private
。在代码中如何调用它的一个示例是:
cout << "total # of S = " << state.sum(&Herd::getS)
"total # of I = " << state.sum(&Herd::getI)
"total birth rate = " << state.sum(&Herd::get_birth)
"total infection rate = " << state.sum(&Herd::get_infection)
等。非常感谢你的帮助,尤其是Potatoswatter。这比我以前使用的繁琐的样板代码要好得多!
- 是否可以将结构数组别名为结构成员数组?
- C++:初始化 constexpr 构造函数中的成员数组
- 使用带有参数包的数组的成员数组初始化类
- C++ 在析构函数调用之前删除的动态成员数组
- 初始化在类类型 #define 中定义的非静态成员数组,不带默认 ctor
- 指向具有不同大小的成员数组的指针
- 用另一个 constexpr 数组对成员数组进行大括号初始化
- 对象成员数组C++默认初始化
- 如何在构造函数中的类成员数组中分配数组值,而无需使用STD库
- 将类成员数组组合到单个数组时性能下降
- 如何将数据从公共方法添加到同一类中的私有成员数组中?
- 如何在C 中的派生类中分配数据成员数组
- C 集合构建器中类成员数组的2D数组大小
- 初始化不可复制、不可移动、显式构造类型的成员数组
- C 指针可以指向字符串文字的静态成员数组
- 成员数组位于何处
- 将对象成员数组与字符串进行比较
- 如何在 c++ 中从对象数组中获取数据成员数组
- 声明模板会员参考另一个类的模板成员数组
- C 初始化成员数组