Скачиваний:
35
Добавлен:
10.09.2019
Размер:
8.59 Кб
Скачать
#include <iostream>

using std::cin;
using std::cout;
using std::endl;

// Файл-помощник

/// Класс без указателей
class ClassWithoutPointers {
 private: /// Доступ к секции возможен только из класса Example

    // Приватные члены следует отличать в именах -- добавлять нижнее подчеркивание в конец
    int secret_number_ = 5;

 protected: /// Доступ к секции возможен из Example и его потомков

    // Какие-либо атрибуты / методы класса

 public: /// Доступ к секции возможен из Example, его потомков и других мест

    int t;

//     =======================
//     Конструктор по умолчанию (ClassWithoutPointers test {5}; : t = 5)
//     ClassWithoutPointers() = default;

//     =======================
//     Конструктор с параметрами
    explicit ClassWithoutPointers(int t) : t(t) {}

//     Или:

//     explicit ClassWithoutPointers(int t) {
//         this->t = t;
//     }

//     =======================
//     Конструктор копирования
    ClassWithoutPointers(const ClassWithoutPointers &arg) = default;

//     Или:

//     ClassWithoutPointers(const ClassWithoutPointers &arg) {
//         secret_number_ = arg.secret_number_;
//         t = arg.t;
//     }

//     =======================
//     Оператор копирования
    ClassWithoutPointers &operator=(const ClassWithoutPointers &arg) = default;

//     Или:

//    ClassWithoutPointers &operator=(const ClassWithoutPointers &arg) {
//        secret_number_ = arg.secret_number_;
//        t = arg.t;
//        return *this;
//    }

//     =======================
//     Конструктор перемещения
    ClassWithoutPointers(ClassWithoutPointers &&arg) = default;

//     Или:

//     ClassWithoutPointers(ClassWithoutPointers &&arg) noexcept {
//         secret_number_ = arg.secret_number_;
//         t = arg.t;
//         /* arg.secret_number_ = 0; */
//         /* arg.t = 0; */
//     }

//     =======================
//     Оператор перемещения
    ClassWithoutPointers &operator=(ClassWithoutPointers &&arg) = default;

//     Или:

//    ClassWithoutPointers &operator=(ClassWithoutPointers &&arg) {
//        secret_number_ = arg.secret_number_;
//        t = arg.t;
//        /* arg.secret_number_ = 0; */
//        /* arg.t = 0; */
//        return *this;
//    }

//     =======================

//    Деструктор
    virtual ~ClassWithoutPointers() = default;

//    или

//    virtual ClassWithoutPointersthoutPointers() {}

//    Для использования в cout
    friend std::ostream &operator<< (std::ostream &os, const ClassWithoutPointers &arg) {
        return os << arg.t << ' ' << arg.secret_number_;
    }
};

/// Класс с указателями
class ClassWithPointers {
 private: /// Доступ к секции возможен только из класса Example

    // Приватные члены следует отличать в именах -- добавлять нижнее подчеркивание в конец
    int *secret_number_ = new int(5);

 protected: /// Доступ к секции возможен из Example и его потомков

    // Какие-либо атрибуты / методы класса

 public: /// Доступ к секции возможен из Example, его потомков и других мест

    int *t;

//     =======================
//     Конструктор по умолчанию не имеет смысла

//     =======================
//     Конструктор с параметрами
    explicit ClassWithPointers(int t) {
        this->t = new int(t);
    }

//     =======================
//     Конструктор копирования
    ClassWithPointers(const ClassWithPointers &arg) {
        *secret_number_ = *arg.secret_number_;
        this->t = new int(*arg.t);
    }

//     =======================
//     Оператор копирования (идиома Copy&Swap)
    ClassWithPointers &operator=(const ClassWithPointers &arg) {
        ClassWithPointers temp(arg);
        std::swap(t, temp.t);
        std::swap(secret_number_, temp.secret_number_);
        return *this;
    }

//     =======================
//     Конструктор перемещения
    ClassWithPointers(ClassWithPointers &&arg) noexcept {
        secret_number_ = arg.secret_number_;
        t = arg.t;
        arg.secret_number_ = nullptr;
        arg.t = nullptr;
    }

//     =======================
//     Оператор перемещения
    ClassWithPointers &operator=(ClassWithPointers &&arg) noexcept {
        std::swap(this->t, arg.t);
        std::swap(this->secret_number_, arg.secret_number_);
        if (arg.t) {
            delete arg.t, arg.t = nullptr;
        }
        if (arg.secret_number_) {
            delete arg.secret_number_, arg.secret_number_ = nullptr;
        }
        return *this;
    }

//     =======================

//    Деструктор
    virtual ~ClassWithPointers() {
        delete t;
        delete secret_number_;
    }

//    Для использования в cout
    friend std::ostream &operator<< (std::ostream &os, const ClassWithPointers &arg) {
        if (arg.t && arg.secret_number_) {
            return os << *arg.t << ' ' << *arg.secret_number_;
        }
        return os;
    }
};

int main() {
    // ====================
    // Класс без указателей
    cout << "======================" << endl;
    cout << "== ClassWithoutPointers ==" << endl;
    cout << "======================" << endl;

    auto *tA = new ClassWithoutPointers(4);

    // Копирование конструктором
    ClassWithoutPointers tB(*tA);
    cout << "======================" << endl;
    cout << "== Copy constructor ==" << endl;
    cout << "tA: " << *tA << endl;
    cout << "tB: " << tB << endl;

    // Копирование присваиванием
    ClassWithoutPointers tC = *tA;
    cout << "======================" << endl;
    cout << "== Copy assignment ==" << endl;
    cout << "tA: " << *tA << endl;
    cout << "tC: " << tC << endl;

    // Перемещение конструктором
    ClassWithoutPointers tD(std::move(*tA));
    cout << "======================" << endl;
    cout << "== Move constructor ==" << endl;
    cout << "tA: " << *tA << endl;
    cout << "tD: " << tD << endl;

    // Перемещение присваиванием
    tC = std::move(tB);
    cout << "======================" << endl;
    cout << "== Move assignment ==" << endl;
    cout << "tB: " << tB << endl;
    cout << "tC: " << tC << endl;
    delete tA, tA = nullptr;


    // ====================
    // Класс с указателями
    cout << endl;
    cout << "======================" << endl;
    cout << "== ClassWithPointers ==" << endl;
    cout << "======================" << endl;

    auto *tpA = new ClassWithPointers(5);

    // Копирование конструктором
    ClassWithPointers tpB(*tpA);
    cout << "======================" << endl;
    cout << "== Copy constructor ==" << endl;
    cout << "tpA: " << *tpA << endl;
    cout << "tpB: " << tpB << endl;

    // Копирование присваиванием
    ClassWithPointers tpC = *tpA;
    cout << "======================" << endl;
    cout << "== Copy assignment ==" << endl;
    cout << "tpA: " << *tpA << endl;
    cout << "tpC: " << tpC << endl;

    // Перемещение конструктором
    ClassWithPointers tpD(std::move(*tpA));
    cout << "======================" << endl;
    cout << "== Move constructor ==" << endl;
    cout << "tpA: " << *tpA << endl;
    cout << "tpD: " << tpD << endl;

    // Перемещение присваиванием
    tpC = std::move(tpB);
    cout << "======================" << endl;
    cout << "== Move assignment ==" << endl;
    cout << "tpB: " << tpB << endl;
    cout << "tpC: " << tpC << endl;
    delete tpA, tpA = nullptr;
}