为数学函数实现乘法运算符C ++ [英] Implementing multiplication operator for mathematical functions C++

查看:67
本文介绍了为数学函数实现乘法运算符C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下抽象基类:

class Function {
 virtual double Eval(double x) const = 0;
};     

我希望能够使用诸如f * g或f-> operator *(g)之类的表达式,其中f和g是函数类的具体对象,例如,在我的主文件中,例如当我想计算时一个定积分,以便我可以写:

I want to be able to use expressions like f * g or f->operator *(g), where f and g are concrete objects of the class Function, in my main file, say for example when I want to calculate a definite integral so that I can write:

AnIntegrationMethod(f*g);

我想出的一个相当简单的方法是声明一个Product类(仅显示头文件,实现很明显):

A rather unsophisticated method I came up with consists of declaring a class Product (only header file shown, the implementation is obvious):

class Product: public Function {
 public: Product(Function *g, Function *f); 
  ~Product(); 
  virtual double Eval(double x) const; //return _g->Eval(x)*_f->Eval(x)
 private: Function *_g; Function *_f;
 };

然后在我的任何功能中

#include "Product.h"

class ConcreteFunction: public Function {
 public: 
   ConcreteFunction(); 
  ~ConcreteFunction(); 
  virtual double Eval(double x) const;
 Function* operator*(Function *f) {return new Product(this, f);}
 };

这实际上适用于简单的东西,但是问题在于运算符*仅在基类的单个派生类中定义,而不是为每个可能的派生类定义.例如,这意味着如果我有一个代表数学函数的具体对象f,我可以调用f-> operator * g,但是如果我想再次调用operator *来获取对象(f-> operator * g)- > operator * f我将无法使用,因为函数f * g没有将*运算符定义为f.

This actually works for simple stuff but the problem is that the operator * is only defined within single derived classes of the base class instead of being defined for every possible derived class. This means, for instance, that if I have a concrete object f representing a mathematical function I can call f->operator *g but if I want to call again the operator * to get the object (f->operator * g)->operator * f I am not going to be able to because the function f* g does not have the * operator defined as f.

我想我应该直接在基类中定义运算符*,但是由于我不知道如何使用该产品,因此我不知道如何实现该运算符,因为我真的不知道如何为该产品获取适当的Eval函数现在,使用Product类,在Function类本身中使用从Function类派生的Product类没有意义.我想我对于通常写以下内容是否正确还很困惑:

I suppose I should define the operator * directly in my base class but then I can't figure out how to implement the operator because I don't really know how to get the proper Eval function for the product since I cannot use the class Product now, it wouldn't make sense to use the class Product derived from the class Function in the class Function itself. I think I'm also quite confused over whether in general is correct to write something like the following:

 Function* Function::operator*(Function *f) {
 Function *g;
 ...
 //operations that allow g to be have the right Eval function
 //which should of the sort this->Eval(x) * f->Eval(x)
 ...
 return g;
 }

任何有关进行方法的提示或建议,将不胜感激.我的水平很基础,我已经编程了两个月了.

Any hints or suggestions on how to proceed are appreciated. My level is very basic, I've been programming two month now.

推荐答案

只是一个草图,您可能会执行以下操作:

Just a sketch, you might do something like this:

#include <memory>

// Base Function: f(x) = x
class Function
{
    protected:
    struct Implementation
    {
        virtual ~Implementation() {}
        virtual double evaluate(double x) const { return x; }
    };

    public:
    Function()
    :   self(std::make_shared<Implementation>())
    {}

    double operator () (double x) const { return self->evaluate(x); }

    protected:
    Function(std::shared_ptr<Implementation> self)
    :   self(self)
    {}

    private:
    std::shared_ptr<Implementation> self;
};
typedef Function Identity;


// Unary Function: u(-f(x))
class UnaryMinus : public Function
{
    protected:
    struct Implementation : Function::Implementation
    {
        Function f;
        Implementation(Function f)
        :   f(f)
        {};

        virtual double evaluate(double x) const override { return -f(x); }
    };

    public:
    UnaryMinus(Function f)
    :   Function(std::make_shared<Implementation>(f))
    {}
};

// Binary Function: u(f(x) + g(x))
class BinaryAdd : public Function
{
    protected:
    struct Implementation : Function::Implementation
    {
        Function f;
        Function g;
        Implementation(Function f, Function g)
        :   f(f), g(g)
        {};

        virtual double evaluate(double x) const override { return f(x) + g(x); }
    };

    public:
    BinaryAdd(Function f, Function g)
    :   Function(std::make_shared<Implementation>(f, g))
    {}
};

// Binary Function: u(f(x) * g(x))
class BinaryMultiply : public Function
{
    protected:
    struct Implementation : Function::Implementation
    {
        Function f;
        Function g;
        Implementation(Function f, Function g)
        :   f(f), g(g)
        {};

        virtual double evaluate(double x) const override { return f(x) * g(x); }
    };

    public:
    BinaryMultiply(Function f, Function g)
    :   Function(std::make_shared<Implementation>(f, g))
    {}
};

inline UnaryMinus operator - (Function f) { return UnaryMinus(f); }
inline BinaryAdd operator + (Function f, Function g) { return BinaryAdd(f, g); }
inline BinaryMultiply operator * (Function f, Function g) { return BinaryMultiply(f, g); }

#include <iostream>
int main() {
    Identity x;
    Function result = -x * (x + x) + x;
    std::cout << result(2) << '\n';
}

这篇关于为数学函数实现乘法运算符C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆