c++ - 对象超出其范围 c++
问题描述
我想知道是否有一种方法可以让对象超过其范围的生命周期并且仍然可用,例如下面显示的示例。从广义上讲,我试图根据输入参数使用不同类型的对象。if-else
如果语句与调用在同一范围内,则可以轻松解决此问题,calc_force
但这肯定会阻碍程序的性能。
我查看了一些可能的解决方案std::function
,std::shared_ptr
但无济于事。我不确定我是否以正确的心态使用 and 的类包装器来解决这个MD_tools::GCM_force
问题MD_tools::GCM_force
。任何帮助将不胜感激。
std::tuple<double, double> GCM_pp::get_force(double &r, double m, double C) {
auto [ff, u] = MD_tools::GCM_force(r, m, C); // This is static
return std::make_tuple(ff, u);
}
std::tuple<double, double> Exp_pp::get_force(double &r, double m, double C) {
auto [ff, u] = MD_tools::Exp_force(r, m, C); // This is static
return std::make_tuple(ff, u);
}
void simulate(std::string pp_type, size_t step, double POWER, double A_CST{
// Normally the if-else loop contains a couple dozen if statements
if (pp_type == "GCM") GCM_pp potential;
else Exp_pp potential;
for (step = 0; step < step_max; ++step) { // typical values: step ~1,000,000
size_t i, j;
for (i = 0; i < N - 1; ++i) { // typical values: N ~10,000
for (j = i + 1; j < N; ++j) {
// stuff happening ...
double r = sqrt((x * x) + (y * y) + (z * z));
auto [ff, temp_u] = potential.calc_force(r, POWER, A_CST);
// stuff happening ...
}
}
}
}
解决方案
这是多态性和类工厂可以用来做的事情,例如:
class Base_pp
{
public:
virtual ~Base_pp() {}
virtual std::tuple<double, double> get_force(double &r, double m, double C) = 0;
};
class GCM_pp : public Base_pp
{
public:
std::tuple<double, double> get_force(double &r, double m, double C) override {
auto [ff, u] = MD_tools::GCM_force(r, m, C); // This is static
return std::make_tuple(ff, u);
}
};
class Exp_pp : public Base_pp
{
public:
std::tuple<double, double> get_force(double &r, double m, double C) override {
auto [ff, u] = MD_tools::Exp_force(r, m, C); // This is static
return std::make_tuple(ff, u);
}
};
...
using funcType = std::unique_ptr<Base_pp> (*)();
std::map<std::string, funcType> make_funcs = {
{"GCM", []() -> std::unique_ptr<Base_pp> { return std::make_unique<GCM_pp>(); }},
...
{"Exp", []() -> std::unique_ptr<Base_pp> { return std::make_unique<Exp_pp>(); }}
};
std::unique_ptr<Base_pp> make_pp(std::string pp_type) {
funcType func = make_funcs[pp_type];
if (!func) func = make_funcs["Exp"];
return func();
}
...
void simulate(std::string pp_type, size_t step, double POWER, double A_CST) {
std::unique_ptr<Base_pp> potential = make_pp(pp_type);
for (step = 0; step < step_max; ++step) { // typical values: step ~1,000,000
size_t i, j;
for (i = 0; i < N - 1; ++i) { // typical values: N ~10,000
for (j = i + 1; j < N; ++j) {
// stuff happening ...
double r = sqrt((x * x) + (y * y) + (z * z));
auto [ff, temp_u] = potential->get_force(r, POWER, A_CST);
// stuff happening ...
}
}
}
}
或者,您的示例中实际上不需要多态性。由于您的类不使用实例数据,因此您可以尝试更多类似的方法:
class GCM_pp
{
public:
static std::tuple<double, double> get_force(double &r, double m, double C) {
auto [ff, u] = MD_tools::GCM_force(r, m, C); // This is static
return std::make_tuple(ff, u);
}
};
class Exp_pp
{
public:
static std::tuple<double, double> get_force(double &r, double m, double C) {
auto [ff, u] = MD_tools::Exp_force(r, m, C); // This is static
return std::make_tuple(ff, u);
}
};
...
using funcType = std::tuple<double, double> (*)(double&, double, double);
std::map<std::string, funcType> get_force_funcs = {
{"GCM", &GCM_pp::get_force},
...
{"Exp", &Exp_pp::get_force}
};
funcType get_force_func(std::string pp_type) {
funcType func = get_force_funcs[pp_type];
if (!func) func = get_force_funcs["Exp"];
return func;
}
...
void simulate(std::string pp_type, size_t step, double POWER, double A_CST) {
funcType get_force = get_force_func(pp_type);
for (step = 0; step < step_max; ++step) { // typical values: step ~1,000,000
size_t i, j;
for (i = 0; i < N - 1; ++i) { // typical values: N ~10,000
for (j = i + 1; j < N; ++j) {
// stuff happening ...
double r = sqrt((x * x) + (y * y) + (z * z));
auto [ff, temp_u] = get_force(r, POWER, A_CST);
// stuff happening ...
}
}
}
}
或这个:
class GCM_pp
{
public:
static std::tuple<double, double> get_force(double &r, double m, double C) {
auto [ff, u] = MD_tools::GCM_force(r, m, C); // This is static
return std::make_tuple(ff, u);
}
};
class Exp_pp
{
public:
static std::tuple<double, double> get_force(double &r, double m, double C) {
auto [ff, u] = MD_tools::Exp_force(r, m, C); // This is static
return std::make_tuple(ff, u);
}
};
...
template<typename T>
void do_simulate(size_t step, double POWER, double A_CST) {
for (step = 0; step < step_max; ++step) { // typical values: step ~1,000,000
size_t i, j;
for (i = 0; i < N - 1; ++i) { // typical values: N ~10,000
for (j = i + 1; j < N; ++j) {
// stuff happening ...
double r = sqrt((x * x) + (y * y) + (z * z));
auto [ff, temp_u] = T::get_force(r, POWER, A_CST);
// stuff happening ...
}
}
}
}
using funcType = void (*)(size_t, double, double);
std::map<std::string, funcType> simulate_funcs = {
{"GCM", &do_simulate<GCM_pp>},
...
{"Exp", &do_simulate<Exp_pp>}
};
funcType get_simulate_func(std::string pp_type) {
funcType func = simulate_funcs[pp_type];
if (!func) func = simulate_funcs["Exp"];
return func;
}
...
void simulate(std::string pp_type, size_t step, double POWER, double A_CST) {
funcType simulate_func = get_simulate_func(pp_type);
simulate_func(step, POWER, A_CST);
}
推荐阅读
- airflow - 安排气流 dag 30 秒
- javascript - 承诺在其他代码位置解析后运行代码
- python - 如何将python集成到automake并在python语法错误时退出构建过程
- lstm - Tensorflow seq2seq 模型,损失值不错,但预测错误
- r - 如何一遍又一遍地重复一个表达式,而不必一直复制和粘贴它?
- gradle - 我怎样才能找出哪个库依赖于 junit 年份?
- geometry - 覆盖球体的最大非重叠球体数?
- excel - 等到在 selenium VBA 中加载 Web 应用程序
- java - 如何播放 Jar 文件中资源文件夹中的 MP3 文件?
- python - 使用参数创建数组/矩阵