Скачиваний:
37
Добавлен:
20.09.2019
Размер:
10.46 Кб
Скачать
#include <iostream>
#include <string>
#include <stdexcept>
 
using std::cin;
using std::cout;
using std::endl;
using std::string;
 
class COne {
 protected:
    long L;
    string S;
 
 public:
 
    // Конструктор
    explicit COne(string input = "", long L = 0) : S(std::move(input)), L(L) {}
 
    // Конструктор копирования
    COne(const COne &arg) {
        L = arg.L;
        S = arg.S;
    }
 
    // Оператор копирования
    COne &operator=(const COne &arg) {
        COne temp(arg);
        std::swap(L, temp.L);
        std::swap(S, temp.S);
        return *this;
    }
 
    // Конструктор перемещения
    COne(COne &&arg) noexcept {
        L = arg.L, arg.L = 0;
        S = std::move(arg.S);
    }
 
    // Оператор перемещения
    COne &operator=(COne &&arg) noexcept {
        if (this != &arg) {
            std::swap(L, arg.L);
            std::swap(S, arg.S);
            arg.L = 0, arg.S.clear();
        }
        return *this;
    }
 
    // Деструктор
    virtual ~COne() {
        S.clear();
    };
 
    // Получение доступа к значению L
    const long &getValue() const {
        return L;
    }
 
    // Получение доступа к строке S
    const string &getString() const {
        return S;
    }
 
    // Длина строки
    size_t len() const {
        return S.size();
    }
 
    // Печать полей класса
    virtual void print() const {
        cout << "COne {" << L << ", \"" << S << "\"}";
    }
 
    friend class CTwo;
    friend class CThree;
    friend class CFour;
};
 
class CTwo {
 protected:
    string S;
    COne *P; // ОТНОШЕНИЕ ВКЛЮЧЕНИЯ
 
 public:
 
    // Конструктор
    explicit CTwo(string s = "", string ps = "", int number = 0) : S(std::move(s)) {
        P = new COne(std::move(ps), number);
    }
 
    // Конструктор копирования
    CTwo(const CTwo &arg) {
        P = new COne(*arg.P);
        S = arg.S;
    }
 
    // Оператор копирования
    CTwo &operator=(const CTwo &arg) {
        CTwo temp(arg);
        std::swap(P, temp.P);
        std::swap(S, temp.S);
        return *this;
    }
 
    // Конструктор перемещения
    CTwo(CTwo &&arg) noexcept {
        P = arg.P, arg.P = nullptr;
        S = std::move(arg.S);
    }
 
    // Оператор перемещения
    CTwo &operator=(CTwo &&arg) noexcept {
        if (this != &arg) {
            std::swap(P, arg.P);
            std::swap(S, arg.S);
            delete arg.P, arg.P = nullptr;
            arg.S.clear();
        }
        return *this;
    }
 
    // Деструктор
    virtual ~CTwo() {
        delete P;
        S.clear();
    }
 
    // Получение доступа к объекту типа COne
    const COne *getCOne() const {
        return P;
    }
 
    // Получение доступа к строке S
    const string &getString() const {
        return S;
    }
 
    // Длина строки
    size_t len() const {
        return S.size();
    }
 
    // Печать полей класса
    virtual void print() const {
        cout << "CTwo [ ";
        if (P) {
            cout << '\"' << S << "\", ";
            P->print();
        } else { cout << "undefined"; }
        cout << " ]";
    }
};
 
class CThree : public CTwo { // ОТНОШЕНИЕ НАСЛЕДОВАНИЯ
 protected:
    double *a;
 
 public:
 
    // Конструктор
    explicit CThree(string s, string ps, int number = 0) : CTwo(std::move(s), std::move(ps), number) {
        if (number > 0) {
            a = new double[number] {0};
        } else { throw std::bad_array_new_length(); }
    }
 
    // Конструктор копирования
    CThree(const CThree &arg) : CThree(arg.S, arg.P->S, arg.P->L) {
        std::copy(arg.a, arg.a + P->L, a);
    }
 
    // Оператор копирования
    CThree &operator=(const CThree &arg) {
        CThree temp(arg);
        swap(*this, temp);
        return *this;
    }
 
    // Конструктор перемещения
    CThree(CThree &&arg) noexcept : CTwo(std::move(arg)) {
        a = arg.a, arg.a = nullptr;
    }
 
    // Оператор перемещения
    CThree &operator=(CThree &&arg) noexcept {
        if (this != &arg) {
            swap(*this, arg);
            arg.S.clear();
            delete arg.P, arg.P = nullptr;
            delete[] arg.a, arg.a = nullptr;
        }
        return *this;
    }
 
    // Деструктор
    virtual ~CThree() {
        delete[] a;
    }
 
    // Оператор индексации
    double &operator[](size_t idx) {
        return a[idx];
    }
 
    // Печать полей класса
    void print() const override {
        cout << "CThree [ ";
        CTwo::print();
        if (a) {
            cout << ", [" << a[0];
            for (size_t i = 0; i < P->L; ++i) {
                cout << ", " << a[i];
            }
            cout << "]";
        } else { cout << " undefined"; }
        cout << " ]";
    }
 
    // Дружественная функция, меняющая поля двух объектов местами
    friend void swap(CThree &first, CThree &second) noexcept {
        std::swap(first.P, second.P);
        std::swap(first.a, second.a);
        std::swap(first.S, second.S);
    }
};
 
 
class CFour : public CThree { // ОТНОШЕНИЕ НАСЛЕДОВАНИЯ
 protected:
    COne *point; // ОТНОШЕНИЕ ВКЛЮЧЕНИЯ
 
 public:
 
    // Конструктор
    explicit CFour(string s, string ps, string cps, int number = 0) : CThree(std::move(s), std::move(ps), number) {
        point = new COne(std::move(cps), number);
    }
 
    // Конструктор копирования
    CFour(const CFour &arg) : CThree(arg) {
        point = new COne(arg.point->S, arg.point->L);
    }
 
    // Оператор присваивания копированием
    CFour &operator=(const CFour &arg) {
        CFour temp(arg);
        swap(*this, temp); // not std! see below
        return *this;
    }
 
    // Конструктор перемещения
    CFour(CFour &&arg) noexcept : CThree(std::move(arg)) {
        point = arg.point, arg.point = nullptr;
    }
 
    // Оператор присваивания перемещением
    CFour &operator=(CFour &&arg) noexcept {
        if (this != &arg) {
            swap(*this, arg);
            arg.S.clear();
            delete arg.P, arg.P = nullptr;
            delete arg.a, arg.a = nullptr;
            delete arg.point, arg.point = nullptr;
        }
        return *this;
    }
 
    // Деструктор
    virtual ~CFour() {
        delete point;
    }
 
    // Получение доступа ко второму объекту типа COne
    const COne *getCOnePoint() const {
        return point;
    }
 
    // Печать полей класса
    void print() const override {
        cout << "CFour [ ";
        CThree::print();
        if (point) {
            cout << ", " << point->L << ", \'" << point->S << '\'';
        } else { cout << " undefined"; }
        cout << " ]";
    }
 
    // Дружественная функция, меняющая поля двух объектов местами
    friend void swap(CFour &first, CFour &second) noexcept {
        std::swap(first.point, second.point);
        std::swap(first.P, second.P);
        std::swap(first.a, second.a);
        std::swap(first.S, second.S);
    }
};
 
void printAll(CTwo **t, size_t n) {
    for (size_t i = 0; i < n; ++i) {
        t[i]->print(), cout << endl;
    }
}
 
void test() {
    CTwo *Array[3];
    Array[0] = new CTwo("Text string 1", "Text string 2", 3);
    Array[1] = new CThree("Text string 3", "Text string 4", 4);
    Array[2] = new CFour("Text string 5", "Text string 6", "Text string 7", 5);
    printAll(Array, 3);
    delete Array[0];
    delete Array[1];
    delete Array[2];
}

int main() {
    const int N = 5;

    // Создание объекта
    CFour tA("Text string", "Text string 2", "Text string 2 3", N);

    // Вызов метода print() для печати информации об объекте
    cout << "tA: ", tA.print(), cout << endl;

    // Вывод длин строк
    cout << "Lengths tA: " << tA.len() << ' ' << tA.getCOne()->len() << ' ' << tA.getCOnePoint()->len() << endl;
    cout << "Strings tA: " << tA.getString() << ' ' << tA.getCOne()->getString() << ' ' << tA.getCOnePoint()->getString() << endl;
    cout << "Values tA: " << tA.getCOne()->getValue() << ' ' << tA.getCOnePoint()->getValue() << endl;

    // Заполнение массива чисел типа double рандомными числами от 0 до 99
    for (size_t i = 0; i < N; ++i) {
        tA[i] = rand() % 100; 
    }

    // Копирование конструктором
    cout << "======================" << endl;
    cout << "== Copy constructor ==" << endl;
    CFour tC(tA);
    cout << "tA: ", tA.print(), cout << endl;
    cout << "tC: ", tC.print(), cout << endl;

    // Копирование присваиванием
    cout << "=====================" << endl;
    cout << "== Copy assignment ==" << endl;
    tC = tA;
    cout << "tA: ", tA.print(), cout << endl;
    cout << "tC: ", tC.print(), cout << endl;
    // Перемещение конструктором
    cout << "======================" << endl;
    cout << "== Move constructor ==" << endl;
    CFour tD(std::move(tA));
    cout << "tA: ", tA.print(), cout << endl;
    cout << "tD: ", tD.print(), cout << endl;
    // Перемещение присваиванием
    cout << "=====================" << endl;
    cout << "== Move assignment ==" << endl;
    tD = std::move(tC);
    cout << "tC: ", tC.print(), cout << endl;
    cout << "tD: ", tD.print(), cout << endl;
    // Тест
    cout << "\nTEST:\n";
    test();
}
Соседние файлы в папке Решения лабораторных работ (местами есть ошибки)