【问题标题】:Implementation of virtual functions from a third party class从第三方类实现虚函数
【发布时间】:2023-12-05 11:57:01
【问题描述】:

总结
我想设计一个类来保存我所有的问题数据,以便它的成员函数可用于将信息传递给第三方成员函数。如何为以下两个功能做到这一点?

我的问题:

我正在编写一个科学计算程序。为了解决我的问题,我必须使用一些第三方库。目前我正在使用 Ipopt(用于数值优化)。

要使用 Ipopt,我必须通过以下方式提供足够的信息。
首先,我需要创建一个应该继承第三方类 TNLP 的类。
然后我必须提供8个虚函数的实现,其中两个是下面的实现。

// MyNLP is the class which I coded to inherit from TNLP.
bool MyNLP::get_starting_point(Index n, bool init_x, Number* x,
                           bool init_z, Number* z_L, Number* z_U,
                           Index m, bool init_lambda,
                           Number* lambda)
{
   // Here, we assume we only have starting values for x, if you code
   // your own NLP, you can provide starting values for the others if
   // you wish.
    assert(init_x == true);
    assert(init_z == false);
    assert(init_lambda == false);

   // we initialize x in bounds, in the upper right quadrant
    x[0]=0.5;
    x[1]=1.5;
    return true;
}

bool MyNLP::eval_f(Index n, const Number* x, bool new_x, Number& 
obj_value)
{
    // return the value of the objective function
   Number x2 = x[1];
   obj_value = -(x2 - 2.0) * (x2 - 2.0);
   return true;
}

在上述实现中,我直接为函数调用中的参数提供了值。现在为了使程序更通用,我希望使用一个包含有关我的问题的所有信息的类,并在第三方虚函数中使用函数成员,而不是直接在上述函数中输入所需的信息。

例如,如果NLP 是保存我的问题内容的类,m_nlp 是它在类MyNLP 中的事件,那么我将重写虚函数如下。

bool MyNLP::get_starting_point(Index n, bool init_x, Number* x,
                           bool init_z, Number* z_L, Number* z_U,
                           Index m, bool init_lambda,
                           Number* lambda)
{
   // Here, we assume we only have starting values for x, if you code
   // your own NLP, you can provide starting values for the others if
   // you wish.
    assert(init_x == true);
    assert(init_z == false);
    assert(init_lambda == false);

    x = m_nlp->get_initial_values();

}

bool MyNLP::eval_f(Index n, const Number* x, bool new_x, Number& 
obj_value)
{
    // return the value of the objective function
    obj_value = m_nlp->get_obj_value();
}

但我不能以上述方式执行此操作,因为第二个函数使用 x 来计算 object_val。如何设计一个类来保存所有数据并使用其成员函数向 Ipopt 提供所需的信息。

我认为的解决方案:

std::vector<Number> values 定义为nlp 类的成员,并将x 指向values 的第一个元素。

 x = &(m_nlp->get_values()).at(0);

在第二个函数中,我可以修改values而不是x并计算obj_val

【问题讨论】:

  • 我不明白“在上述实现中,我直接为函数调用中的参数提供了值。” (以及除此之外的任何东西)。 “函数参数”是指 x[0] =0.5 吗?我真的不明白这个问题。我的意思是这是你的班级,只要从你喜欢的任何地方获取参数,例如x[0]= this->getX0()
  • @tobi303、x等参数在第三方类中定义。但我必须为它提供价值。我正在寻找一种通用的方式来赋予它价值
  • 似乎通用的方法是覆盖他们的虚拟方法。我不明白为什么你还需要一些东西
  • @tobi303,我的问题可以通过不同的数值优化算法来解决。 Ipopt 是一种算法,但还有其他算法。我正在设计一个包含我的问题内容(即变量和方法)的类,以便我可以将这个通用类与不同的库包一起使用

标签: c++ function class parameter-passing pass-by-reference


【解决方案1】:

您可以从 MyNLP 派生一个类。或者

class NLPWithStuff : public MyNLP {
   //... 
   virtual bool get_starting_point(/*...*/) 
    {
        // optional boost::signals that do their stuff ??
        // do my stuff, set flags so that no-one touches my stuff 
        // don't assert

        return MyNLP::get_starting_point(/*.+.*/);
    }
};

您必须声明 MyNLP::get_starting_point virtual 才能使其工作。

【讨论】:

  • 希望对我有用。但我是初学者,你能详细说明一下吗?
  • 因此,NLPWithStuff 继承自 MyNLP,而 MyNLP 继承自 TNLP。 NLPWithStuff 中提供了 MyNLP 函数的实现。不是吗?
  • 没有。派生类提供了额外的功能,但允许层次结构中的其他类做自己的事情,或者可以覆盖它们。 MyNLP 仍然负责做它知道该做的事情。
最近更新 更多