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

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

template <class T>
class Vector {
 private:

    // Число элементов
    size_t n_;
    // Массив со значениями
    T *values_ = nullptr;

 public:

    // Конструктор
    explicit Vector(size_t n = 3) : n_(n) {
        if (n_ > 0) {
            values_ = new T[n_] {0};
        }
    }

    // Конструктор копирования
    Vector(const Vector &arg) : Vector(arg.n_) {
        n_ = arg.n_;
        if (n_ > 0) {
            values_ = new T[n_];
            std::copy(arg.values_, arg.values_ + arg.n_, values_);
        }
    }

    // Оператор копирования
    Vector &operator=(const Vector &arg) {
        Vector temp(arg);
        swap(*this, temp);
        return *this;
    }

    // Конструктор перемещения
    Vector(Vector &&arg) noexcept {
        n_ = arg.n_, arg.n_ = 0;
        values_ = arg.values_, arg.values_ = nullptr;
    }

    // Оператор перемещения
    Vector &operator=(Vector &&arg) noexcept {
        if (this != &arg) {
            swap(*this, arg);
            delete[] arg.values_, arg.values_ = nullptr;
            arg.n_ = 0;
        }
        return *this;
    }

    // Деструктор
    virtual ~Vector() {
        delete[] values_;
    }

    // Оператор индексации
    T &operator[](size_t k) {
        return values_[k];
    }

    // Метод для получения размерности вектора
    size_t size() const {
        return n_;
    }

    // Оператор сложения векторов
    Vector operator+(const Vector &arg) const noexcept(false) {
        if (n_ == arg.n_) {
            Vector result(n_);
            for (size_t i = 0; i < n_; ++i) {
                result.values_[i] = values_[i] + arg.values_[i];
            }
            return result;
        }
        throw std::invalid_argument("Vector. Operator +. N != ARG.N");
    }

    // Оператор сложения векторов и присваивания
    Vector &operator+=(const Vector &arg) noexcept(false) {
        if (n_ == arg.n_) {
            for (size_t i = 0; i < n_; ++i) {
                values_[i] = values_[i] + arg.values_[i];
            }
            return *this;
        }
        throw std::invalid_argument("Vector. Operator +=. N != ARG.N");
    }

    // Оператор смены знака вектора
    Vector operator-() const {
        Vector result(n_);
        for (size_t i = 0; i < n_; ++i) {
            result.values_[i] = -values_[i];
        }
        return result;
    }

    // Оператор вычитания
    Vector operator-(const Vector &arg) const noexcept(false) {
        if (n_ == arg.n_) {
            Vector result(n_);
            for (size_t i = 0; i < n_; ++i) {
                result.values_[i] = values_[i] - arg.values_[i];
            }
            return result;
        }
        throw std::invalid_argument("Vector. Operator -. N != ARG.N");
    }

    // Оператор вычитания векторов и присваивания
    Vector &operator-=(const Vector &arg)  noexcept(false) {
        if (n_ == arg.n_) {
            for (size_t i = 0; i < n_; ++i) {
                values_[i] = values_[i] - arg.values_[i];
            }
            return *this;
        }
        throw std::invalid_argument("Vector. Operator -=. N != ARG.N");
    }

    // Метод вычисления длины вектора
    T length() const {
        T s = 0;
        for (size_t i = 0; i < n_; ++i) {
            s += values_[i] * values_[i];
        }
        return sqrt(s);
    }

    // Метод вычисления скалярного произведения векторов
    T scalar(const Vector &arg) const noexcept(false) {
        if (n_ == arg.n_) {
            T s = 0;
            for (size_t i = 0; i < n_; ++i) {
                s += values_[i] * arg.values_[i];
            }
            return s;
        }
        throw std::invalid_argument("Vector. Method scalar. N != ARG.N");
    }

    // Оператор == сравнения векторов
    bool operator==(const Vector &arg) const {
        if (n_ == arg.n_) {
            for (size_t i = 0; i < n_; ++i) {
                if (values_[i] != arg.values_[i]) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    // Оператор != сравнения векторов
    bool operator!=(const Vector &arg) const {
        return !( operator==(arg) );
    }

    // Оператор приведения к типу bool
    explicit operator bool() {
        return n_ != 0;
    }

    // Дружественный оператор для вывода вектора в выходной поток os (cout, ...)
    friend std::ostream &operator<<(std::ostream &os, const Vector &arg) {
        if (arg.n_ > 0) {
            os << '{' << arg.values_[0];
            for (size_t i = 1; i < arg.n_; ++i) {
                os << ", " << arg.values_[i];
            }
            return os << '}';
        }
        return os;
    }

    friend void swap(Vector &first, Vector &second) noexcept {
        std::swap(first.n_, second.n_);
        std::swap(first.values_, second.values_);
    }
};

int main() {
    const size_t N = 3;
    Vector<double> va(N), vb(N);
    for (size_t i = 0; i < N; ++i) {
        va[i] = rand() % 100;
        vb[i] = rand() % 100;
    }
    cout << "Vector A dimension: " << va.size() << endl;
    cout << "Vector B dimension: " << vb.size() << endl;
    cout << "Vector A: " << va << endl;
    cout << "-Vector A: " << -va << endl;
    cout << "Vector B: " << vb << endl;
    cout << "-Vector B: " << -vb << endl;
    cout << "Vector A + Vector B: " << va + vb << endl;
    Vector<double> vc(va); // Конструктор копирования
    vc += vb;
    cout << "Vector C (Vector A + Vector B): " << vc << endl;
    cout << "Vector C == Vector A + Vector B ? " << ( vc == va + vb ? "TRUE" : "FALSE" ) << endl;
    cout << "Vector A - Vector B: " << va - vb << endl;
    Vector<double> vd = va; // Оператор копирования
    vd -= vb;
    cout << "Vector D (Vector A - Vector B): " << vd << endl;
    cout << "Vector D == Vector A - Vector B ? " << ( vd == va - vb ? "TRUE" : "FALSE" ) << endl;
    cout << "Vector A * Vector B (scalar): " << va.scalar(vb) << endl;
    cout << "Vector A length: " << va.length() << endl;
    cout << "Vector B length: " << vb.length() << endl;
    cout << "Vector D: " << vd << endl;
    Vector<double> vf(std::move(vd)); // Конструктор перемещения
    cout << "Vector D: " << vd << endl;
    cout << "Vector F: " << vf << endl;
    vc = std::move(vf); // Оператор перемещения
    cout << "Vector F: " << vf << endl;
    cout << "Vector C: " << vc << endl;
}
Соседние файлы в папке Решения лабораторных работ (местами есть ошибки)