5. Öröklés

Czirkos Zoltán · 2019.02.27.

Öröklés: Mappák és fájlok, IMSc: kifejezések és deriválás

1. Mappák és fájlok


#include <string>
#include <iostream>

// absztrakt alaposztály
// abc  abstract base class
class Bejegyzes {
    private:
        std::string nev;

    public:
        Bejegyzes(char const *n) : nev(n) {}

        std::string const & get_nev() const {
            return nev;
        }

        // tisztán virtuális függvény
        // pure virtual function
        virtual int get_meret() const = 0;
};

class Fajl : public Bejegyzes {
    private:
        int meret;

    public:
        Fajl(char const *n, int m) : Bejegyzes(n), meret(m) {
        }

        int get_meret() const {
            return meret;
        }
};

class Mappa : public Bejegyzes {
    private:
        Bejegyzes* bejegyzesek[100];
        int db;

    public:
        Mappa(char const *n) : Bejegyzes(n), db(0) {
        }

        void betesz(Bejegyzes* b) {
            bejegyzesek[db++] = b;
        }

        int get_meret() const {
            int osszmeret = 0;
            for (int i = 0; i < db; ++i)
                osszmeret += bejegyzesek[i]->get_meret();
            return osszmeret;
        }
};


int main() {
    Mappa m1("Filmek");
    Fajl f1("film1.avi", 750);
    Fajl f2("film2.avi", 800);
    m1.betesz(&f1);     // Fajl* -> Bejegyzes*
    m1.betesz(&f2);
    Mappa m2("Sorozatok");
    m1.betesz(&m2);     // Mappa* -> Bejegyzes*

    std::cout << m1.get_meret();
}

2. IMSc: kifejezések és deriválás

#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;
}