#include <iostream>
class Kifejezes {
public:
virtual double kiertekel(double x) const = 0;
virtual void kiir(std::ostream & os) const = 0;
virtual Kifejezes * derivalt() const = 0;
virtual Kifejezes * masolat() const = 0;
virtual ~Kifejezes() {}
};
std::ostream & operator<< (std::ostream & os, Kifejezes const & k) {
k.kiir(os);
return os;
}
class Szam : public Kifejezes {
private:
double c;
public:
Szam(double c) : c(c) {}
virtual double kiertekel(double) const {
return c;
}
virtual void kiir(std::ostream & os) const {
os << c;
}
virtual Kifejezes * derivalt() const {
return new Szam(0);
}
virtual Kifejezes * masolat() const {
return new Szam(*this);
}
};
class Valtozo : public Kifejezes {
public:
virtual double kiertekel(double x) const {
return x;
}
virtual void kiir(std::ostream & os) const {
std::cout << 'x';
}
virtual Kifejezes * derivalt() const {
return new Szam(1);
}
virtual Kifejezes * masolat() const {
return new Valtozo(*this);
}
};
class Operator : public Kifejezes {
protected:
Kifejezes *op1, *op2;
public:
Operator(Kifejezes *op1, Kifejezes *op2)
: op1(op1), op2(op2) {}
Operator(Operator const & masik)
: op1(masik.op1->masolat()), op2(masik.op2->masolat()) {}
~Operator() {
delete op1;
delete op2;
}
};
class Osszeg : public Operator {
public:
Osszeg(Kifejezes *op1, Kifejezes *op2)
: Operator(op1, op2) {}
virtual double kiertekel(double x) const {
return op1->kiertekel(x) + op2->kiertekel(x);
}
virtual void kiir(std::ostream & os) const {
os << '(';
op1->kiir(os);
os << '+';
op2->kiir(os);
os << ')';
}
virtual Kifejezes * derivalt() const {
return new Osszeg(op1->derivalt(), op2->derivalt());
}
virtual Kifejezes * masolat() const {
return new Osszeg(*this);
}
};
class Szorzat : public Operator {
public:
Szorzat(Kifejezes *op1, Kifejezes *op2)
: Operator(op1, op2) {}
virtual double kiertekel(double x) const {
return op1->kiertekel(x) * op2->kiertekel(x);
}
virtual void kiir(std::ostream & os) const {
op1->kiir(os);
os << '*';
op2->kiir(os);
}
virtual Kifejezes * derivalt() const {
return new Osszeg(
new Szorzat(op1->derivalt(), op2->masolat()),
new Szorzat(op1->masolat(), op2->derivalt()));
}
virtual Kifejezes * masolat() const {
return new Szorzat(*this);
}
};
int main() {
// 2 + 3*x
Kifejezes *k = new Szorzat(
new Osszeg(
new Szam(3),
new Valtozo
),
new Szam(2)
);
std::cout << *k << "=" << k->kiertekel(10) << std::endl;
Kifejezes *kd = k->derivalt();
std::cout << *kd << std::endl;
delete k;
delete kd;
return 0;
}