ここでポリモーフィズムを使用できると思います。通貨のリストがあり、それぞれがすべての依存要素の (基本クラスへの) ポインターを持つベクトルを保持します。
update()
基本クラスは、現在の通貨が更新されるたびに呼び出される関数を含めるよう強制します。
depedant 要素は、依存する各通貨のポインターを持ち、これらを使用してupdate()
実装で自分自身を更新します。
#include<iostream>
#include <vector>
class c_node_combi_base;
class currency
{
std::vector<c_node_combi_base*> m_dependant;
double m_val;
public:
double value (void) const { return m_val; }
void reg (c_node_combi_base * p) { m_dependant.push_back(p); }
void update (double val);
};
class c_node_combi_base
{
std::vector<currency*> currencies;
public:
virtual void update (void) = 0;
};
template<size_t N, typename OP> // templated to differentiate types of nodes
class currency_node : public c_node_combi_base
{
};
struct divide_d
{
double operator() (const double x, const double y) const {return x/y;}
};
template<typename OPT> // node type 2
class currency_node<2u, OPT>
: public c_node_combi_base
{
currency *A, *B;
OPT _op;
double m_val;
public:
currency_node (currency * a, currency * b)
: A(a), B(b), _op(), m_val(_op(A->value(), B->value()))
{
A->reg(this);
B->reg(this);
}
void update (void)
{
m_val = _op(A->value(), B->value());
}
double value (void) { return m_val; }
};
void currency::update (double value)
{
m_val = value;
for (size_t i=0; i<m_dependant.size(); ++i)
{
m_dependant[i]->update();
}
}
これにより、次のことが可能になります。
int main (void)
{
currency franc, dinar;
franc.update(9.9);
dinar.update(3.3);
currency_node<2, divide_d> franc_dinar(&franc, &dinar);
std::cout << franc_dinar.value() << std::endl;
dinar.update(1.1); // updates franc_dinar automatically
std::cout << franc_dinar.value() << std::endl;
}
印刷:
3
9
おそらくstd::vector<std::weak_ptr>
、各ノードがstd::shared_ptr
各通貨の を保持している間、通貨の を保持できるため、通貨を参照するノードがなくなるまで、通貨がスコープ外に出たり破棄されたりすることはありません