конструктор композиции получает переменную из переменных-членов - PullRequest
0 голосов
/ 30 января 2019

Я вызываю класс (например, B) в качестве аргумента для другого класса (например, A) (состав).Я хочу сказать классу B получить вашу переменную конструктора из переменной-члена класса A.

Это пример из boost odeint:

lib.h

using namespace boost::numeric::odeint;

/* The type of container used to hold the state vector */
typedef vector<double> state_type;

/* The rhs of x' = f(x) defined as a class */
class harm_osc {
    double m_gam;
public:
    harm_osc( double gam ) : m_gam(gam) { }

    void operator() ( const state_type &x , state_type &dxdt , const double /* t */ )
    {
        dxdt[0] = x[1];
        dxdt[1] = -x[0] - m_gam*x[1];
    }
};
/*------------------------------------------------------------*/
class osc_solver {


    public:
    osc_solver(const harm_osc &ho) : m_ho(ho) {
        x = {1.0, 0.0}; // start at x=1.0, p=0.0

    }
    void run();

    private:
    harm_osc m_ho;
    state_type x;
    vector<state_type> x_vec;
    vector<double> times;
};

lib.cpp

void osc_solver::run()
{
    size_t steps = integrate(m_ho,
                             x, 0.0, 10.0, 0.1,
                             push_back_state_and_time(x_vec, times));

    /* output */
    for (size_t i = 0; i <= steps; i++)
    {
        cout << times[i] << '\t' << x_vec[i][0] << '\t' << x_vec[i][1] << '\n';
    }
}

main.cpp

int main(int /* argc */ , char** /* argv */ )
{
    osc_solver sol(harm_osc(0.15));
    sol.run();
    return 0;
}

Мне нужно что-то подобное:

osc_solver sol(0.15, harm_osc));

потому что иногда мне нужно передать много переменных классам, которые я использую в них обоих.

Спасибо за любое руководство.

1 Ответ

0 голосов
/ 30 января 2019

Вы можете определить класс osc_solver с помощью параметра шаблона HarmType, который параметризует тип члена osc_solver::m_ho и создать его, перенаправив аргументы конструктора osc_solver.Что-то вроде

#include <utility>

template <class HarmType>
class osc_solver {
public:
     template <class... ArgsType>
     osc_solver(ArgsType&&... parameters_ham) : m_ho(std::forward<ArgsType>(parameters_harm)...) {
        x = {1.0, 0.0}; // start at x=1.0, p=0.0

    }
    void run();

    private:
    HarmType m_ho;
    state_type x;
    vector<state_type> x_vec;
    vector<double> times;
};

Тогда, например, вы можете использовать объект osc_solver как

// harm_osc needs 1 parameter in the constructor
osc_solver<harm_osc> solver(0.15);
// harm_osc_special needs 2 parameters in the constructor
osc_solver<harm_osc_special> solver(0.15, 0.2);

В более общем смысле вы можете определить osc_solver::osc_solver так, чтобы требовать оба параметра, используемые вкласс osc_solver и при построении osc_solver:m_ho, например:

template <class HarmType>
class osc_solver {
public:
    template <class... ArgsType>
    osc_solver(double a, ArgsType&&... parameters_ham) : m_ho(std::forward<ArgsType>(a, parameters_harm)...)
    {
       // Here use parameter a
    }
 // ...
...