#include #include #include using namespace std; class Function { public: virtual double eval(double) const = 0; virtual ~Function(){}; virtual Function * clone() const = 0; }; #define CLONE_(Type) \ virtual Type * clone() const { \ return new Type(*this); \ } class Polynome: public Function { double arr[3]; public: Polynome(double = 0.0, double = 0.0, double = 0.0); double eval(double) const; CLONE_(Polynome); }; Polynome::Polynome(double a, double b, double c) { arr[0] = c; arr[1] = b; arr[2] = a; } double Polynome::eval(double x) const { double res = arr[0]; double p = x; for ( int i = 1; i< 3; ++i, p *= x) { res += arr[i]*p; } return res; } template class Root : public Function { public : double eval(double) const; CLONE_(Root); }; template<> class Root<0> : public Function { //няма корен от 0; // той е абстрактен, защото не дефинира eval. }; template double Root::eval(double x)const { return std::pow(x, 1.0/n); } class Double : public Function { protected: Function const* f, *g; public: Double(const Function &, const Function &); Double(const Double &); ~Double(); }; Double::Double(const Function & a, const Function & b) { f = a.clone(); g = b.clone(); } Double::Double(const Double & other) { f = other.f -> clone(); g = other.g -> clone(); } Double::~Double() { delete f; delete g; } class Composition : public Double { public: Composition(const Function &, const Function &); double eval(double) const; CLONE_(Composition); }; Composition::Composition(const Function & a, const Function & b) : Double(a, b) {} double Composition::eval( double x) const { return f->eval(g->eval(x)); } class Sum : public Double { public: Sum(const Function &, const Function &); double eval(double) const; CLONE_(Sum); }; Sum::Sum(const Function & a, const Function & b) : Double(a, b) {} double Sum::eval( double x) const { return f->eval(x) + g->eval(x); } const Sum operator+(const Function & a, const Function & b) { return Sum(a, b); } int main() { Sum f(Root<5>(), Polynome(2, 0, 1)); Composition c(f, f); //Root<0> r(); //абстрактен cout << f.eval(5.0) << endl; cout << c.eval(5) << endl; }