Главная страница
Навигация по странице:

  • Лабораторная работа №1

  • Цель

  • Конструирование классов и использование объектов пользователя в программах на языке C ». ЛР1. Лабораторная работа 1 по дисциплине Объектноориентированное программирование по теме


    Скачать 64.63 Kb.
    НазваниеЛабораторная работа 1 по дисциплине Объектноориентированное программирование по теме
    АнкорКонструирование классов и использование объектов пользователя в программах на языке C
    Дата16.12.2021
    Размер64.63 Kb.
    Формат файлаdocx
    Имя файлаЛР1.docx
    ТипЛабораторная работа
    #305202


    МИНОБРНАУКИ РОССИИ

    Федеральное государственное бюджетное

    образовательное учреждение высшего профессионального образования

    «Тульский государственный университет»


    Лабораторная работа №1

    по дисциплине

    «Объектно-ориентированное программирование»

    по теме

    «Конструирование классов и использование объектов пользователя в программах на языке C++»

    Выполнил: студент гр. 221291 Волошин М.И.

    Проверил: доцент Скобельцын С.А.

    Тула, 2021

    Цель: Получение навыков разработки и использования классов в программах на языке программирования C++.
    Задание на работу: Спроектируйте класс, наполните его требуемой функциональностью. Предусмотреть наличие общедоступных и частных полей и методов. Сконструировать класс, являющийся дочерним или родительским для указанного в индивидуальном задании. Продемонстрировать переопределение некоторых методов/операций родительского класса. Разработать консольную программу(ы) на C++ демонстрирующую работоспособность методов классов. Вариант 7 (Матрица M x N);
    Приведенный в работе код содержит класс матрицы, а также его дочерний класс квадратной матрицы. Для хранения матрицы используется двумерный динамический массив типа int**. Выделение и освобождение памяти осуществляется вручную, с помощью операторов new и delete. В основном классе реализованы методы заполнения матрицы случайными числами, вывода матрицы на экран, поиска наибольшего и наименьшего элемента. В классе квадратной матрицы дополнительно реализовано вычисление определителя алгоритмом Барейса (модификация метода Гаусса для целочисленных матриц, использующая только целочисленное деление, вследствие чего погрешности при вычислениях отсутствуют). Как известно, для прямоугольных матриц понятие определителя смысла не имеет. Для обоих классов поддерживаются операции матричного сложения и умножения, умножения матрицы на число, проверки матриц на равенство, а также ввода значений матрицы из потока и вывода матрицы в поток (речь о каких угодно потоках, например, cin, cout и т.п.).
    Каждый класс имеет три конструктора:

    - конструктор по умолчанию (создает пустой объект класса и инициализирует его поля значениями по умолчанию, т.е. создает пустую матрицу 0x0)

    Пример: matrix m;

    - стандартный конструктор (принимает на вход количество строк и столбцов новой матрицы, а также флаг, указывающий, стоит ли заполнять матрицу случайными элементами или оставить нулевой).

    Пример: matrix m(5,6,true);

    - конструктор копирования , "copy constructor" - позволяет создать новый объект класса путем копирования уже существующего подобного объекта.

    Что интересно, подставляется компилятором автоматически, но копирование массива, содержащего матрицу, все же пришлось реализовать самому.

    Пример:

    matrix w(5,6,true);

    matrix m(w); или matrix m = w;
    Деструктор же перед удалением объекта матрицы автоматически освобождает память, выделенную ранее под содержащий матрицу массив.
    Операторы, обозначенные в классе, позволяют существенно упростить работу с матрицами. Теперь действия над ними в коде приложения можно записывать простым и очевидным образом:

    Пример: matrix m = a +b +c; (вычислить сумму матриц a,b,c и записать в новую матрицу m)
    Замечание 1: в большинстве функций объекты матриц принимаются по ссылке. Делается это для того, чтобы они не использовались как локальные переменные и, следовательно, не уничтожались при выходе из функции.
    Замечание 2: некоторые методы, указанные в классе, имеют модификатор friend. Они называются "дружественными" и могут иметь доступ ко внутренним полям класса даже если сами располагаются вне этого класса (не являются его членами).
    Замечание 3: некоторые методы после их объявления имеют модификатор const. Это означает, что такая функция не может изменять какие-либо объекты текущего класса и имеет к ним доступ в режиме "только чтение". В противном случае происходит ошибка компиляции.
    Пример работы программы:



    // matrix.h

    #include

    #include
    class matrix {

    protected:

    int nRows;

    int nCols;

    int** arr;

    public:

    matrix::matrix();

    matrix::matrix(int rows, int cols, bool random);

    matrix::matrix(const matrix& m);

    matrix::

    matrix();

    private:

    void initParams();

    void initArray(int rows, int cols);

    void deallocateArray();

    void fillRandom();

    public:

    void printMatrixInfo();

    void printMatrix();

    int getMinElem() const;

    int getMaxElem() const;

    public:

    matrix& operator=(const matrix& m);

    bool operator==(const matrix& b);

    matrix& operator+=(const matrix& m);

    matrix& operator^=(const matrix& m);

    matrix& operator*=(int num);

    matrix operator+(const matrix& b);

    matrix operator^(const matrix& b);

    friend matrix operator*(const matrix &b, int num);

    friend matrix operator*(int num, const matrix &b);

    friend std::ostream& operator<<(std::ostream& os, const matrix& m);

    friend std::istream& operator>>(std::istream& is, matrix& m);

    public:

    // const после определения функции означает, что мы

    // "обещаем" компилятору не изменять в ней члены объекта класса

    int getElemAt(int i, int j) const

    { return (i>=0 && i=0 && j
    int getCols() const { return nCols; }

    int getRows() const { return nRows; }

    void setElemAt(int i, int j, int val) {

    if(i>=0 && i=0 && j
    arr[i][j]=val;

    }

    };
    class squareMatrix : public matrix {

    public:

    squareMatrix() : matrix() {};

    squareMatrix(int size, bool random);

    squareMatrix(matrix &m);

    public:

    int determinant();
    };
    // matrix_oper.cpp

    #include

    #include

    #include "matrix.h"
    // Оператор вывода матрицы в поток

    std::ostream& operator<<(std::ostream& os, const matrix& m)

    {

    char buf[16];

    int min_elem = m.getMinElem(), max_elem = m.getMaxElem();

    if(min_elem<0)

    min_elem=abs(min_elem)*10;

    _itoa(std::max(min_elem, max_elem), buf, 10);

    int value_width = strlen(buf);

    os << "--------------------------------------" << std::endl;

    for(int i=0; i
    {

    for(int j=0; j
    {

    os << std::setw(value_width) << m.arr[i][j];

    os << " ";

    }

    os << std::endl;

    }

    os << "--------------------------------------" << std::endl;

    return os;

    }
    // Оператор ввода матрицы из потока

    std::istream& operator>>(std::istream& is, matrix& m)

    {

    std::cout << "Enter new matrix:" << std::endl;

    for(int i=0;i
    {

    for(int j=0;j
    {

    is >> m.arr[i][j];

    }

    }

    return is;

    }
    // Оператор присвоения (копирует матрицу в новый объект)

    matrix& matrix::operator=(const matrix& m)

    {

    if(this == &m) { return *this; }

    deallocateArray();

    initArray(m.nRows, m.nCols);

    for(int i=0; i
    {

    for(int j=0; j
    {

    arr[i][j] = m.arr[i][j];

    }

    }

    return *this;

    }
    // Оператор сложения

    matrix& matrix::operator+=(const matrix& m)

    {

    if(nRows != m.nRows || nCols != m.nCols) {

    return *this;

    }

    for(int i=0; i
    {

    for(int j=0; j
    {

    arr[i][j]+=m.arr[i][j];

    }

    }

    return *this;

    }
    // Оператор умножения матрицы на скаляр

    matrix& matrix::operator*=(int num)

    {

    for(int i=0; i
    {

    for(int j=0; j
    {

    arr[i][j] *= num;

    }

    }

    return *this;

    }
    // Оператор матричного умножения

    matrix& matrix::operator^=(const matrix& m)

    {

    if(nCols != m.nRows) {

    return *this;

    }

    matrix A(*this);

    deallocateArray();

    initArray(A.nRows,m.nCols);

    int sum = 0;

    for(int i=0; i
    {

    for(int j=0; j
    {

    sum = 0;

    for(int k=0; k
    {

    sum += A.arr[i][k] * m.arr[k][j];

    }

    arr[i][j] = sum;

    }

    }

    return *this;

    }
    // Реализуем C = A + B через оператор сложения

    matrix matrix::operator+(const matrix& b)

    {

    matrix res(*this);

    return res += b;

    }
    // Реализуем C = A.B через оператор матричного умножения

    matrix matrix::operator^(const matrix& b)

    {

    matrix res(*this);

    return res ^= b;

    }
    // Оператор проверки матриц на равенство

    bool matrix::operator==(const matrix& b)

    {

    if(nCols != b.nCols || nRows != b.nRows) return false;

    for(int i=0; i
    {

    for(int j=0; j
    {

    if(getElemAt(i,j) != b.arr[i][j]) return false;

    }

    }

    return true;

    }
    // Реализуем умножение матрицы на скаляр

    matrix operator*(const matrix &b, int num)

    {

    matrix res(b);

    return res*=num;

    }
    // Делаем умножение на скаляр коммутативным

    matrix operator*(int num, const matrix &b) {

    return b * num;

    }

    // matrix_func.cpp

    #include "matrix.h"

    #include

    #include

    #include

    #include
    // Конструктор по умолчанию

    matrix::matrix()

    {

    initParams();

    }
    // Конструктор с параметрами, создает матрицу rows * cols

    // По желанию пользователя заполняет ее случайными числами

    matrix::matrix(int rows, int cols, bool random)

    {

    initParams();

    initArray(rows, cols);

    if(random) fillRandom();

    }
    // Конструктор, позволяющий присвоить объекту класса другой объект класса

    // Копирование массива потребовалось реализовать вручную

    matrix::matrix(const matrix& m)

    {

    initParams();

    *this = m;

    }
    // Деструктор, освобождение памяти (если требуется)

    matrix::matrix()

    {

    deallocateArray();

    }
    // Установка параметров матрицы по умолчанию (пустая матрица)

    void matrix::initParams()

    {

    nRows = 0;

    nCols = 0;

    arr = nullptr;

    }
    // Инициализация и заполнение двумерного массива нулями

    void matrix::initArray(int rows, int cols)

    {

    nRows = rows;

    nCols = cols;

    arr=new int*[nRows];

    for(int i=0; i
    {

    arr[i] = new int[nCols];

    std::fill(&arr[i][0], &arr[i][0]+nCols, 0);

    }

    }
    // Стирание существующего массива

    void matrix::deallocateArray()

    {

    for(int i=0; i
    {

    delete arr[i];

    }

    if(arr != nullptr) delete arr;

    initParams();

    }
    // Вывод матрицы на экран

    void matrix::printMatrix()

    {

    std::cout << *this;

    }
    // Вернуть максимальный элемент матрицы

    int matrix::getMaxElem() const

    {

    std::vector rowMaxValues;

    rowMaxValues.reserve(nRows);

    for(int i=0; i
    {

    rowMaxValues.push_back(*std::max_element(arr[i], arr[i]+nCols));

    }

    return nRows > 0 ? (*std::max_element(rowMaxValues.begin(), rowMaxValues.end())) : INT_MAX;

    }
    // Вернуть минимальный элемент матрицы

    int matrix::getMinElem() const

    {

    std::vector rowMinValues;

    rowMinValues.reserve(nRows);

    for(int i=0; i
    {

    rowMinValues.push_back(*std::min_element(arr[i], arr[i]+nCols));

    }

    return nRows > 0 ? (*std::min_element(rowMinValues.begin(), rowMinValues.end())) : INT_MIN;

    }
    // Печать сведений о размерности матрицы

    void matrix::printMatrixInfo()

    {

    std::cout << "Matrix has " << nCols << " columns and " << nRows << " rows" << std::endl;

    }
    // Заполнение матрицы случайными числами

    void matrix::fillRandom()

    {

    for(int i=0; i
    {

    for(int j=0; j
    {

    arr[i][j] = rand() % 8 +1;

    }

    }

    }
    // squarematrix_func.cpp

    #include "matrix.h"

    #include
    // Конструктор квадратной матрицы (путем обрезания прямоугольной)

    squareMatrix::squareMatrix(matrix &m) :

    matrix(std::min(m.getCols(), m.getRows()), std::min(m.getCols(), m.getRows()), false)

    {

    nCols = std::min(m.getCols(), m.getRows());

    nRows = std::min(m.getCols(), m.getRows());

    for(int i=0; i
    {

    for(int j=0; j
    {

    arr[i][j] = m.getElemAt(i,j);

    }

    }

    }

    // Стандартный конструктор квадратной матрицы размера N*N

    squareMatrix::squareMatrix(int size, bool random) : matrix(size, size, random) {}
    // Вычисление определителя квадратной матрицы

    int squareMatrix::determinant()

    {

    // алгоритм Барейса

    squareMatrix res(*this);

    int p = 1, sign = 1;

    for(int k=0; k
    {

    if(res.arr[k][k] == 0)

    {

    for(int i=k+1; i
    {

    if(res.arr[i][k]!=0)

    {

    std::swap(res.arr[i], res.arr[k]);

    sign *= -1;

    break;

    }

    }

    }

    if(res.arr[k][k] == 0) return 0;

    if(k>0) p = res.arr[k-1][k-1];

    for(int i=k+1; i
    {

    for(int j=k+1; j
    {

    res.arr[i][j]=((res.arr[i][j]*res.arr[k][k]) - (res.arr[i][k]*res.arr[k][j]))/p;

    }

    }

    }

    return res.arr[nCols-1][nCols-1]*sign;

    }

    // main.cpp

    #include "matrix.h"

    #include

    #include
    int main()

    {

    srand(time(0));

    matrix w(3,5,true);

    matrix k(3,5,true);

    std::cout << "Matrix W:" << std::endl;

    w.printMatrix();

    std::cout << "Matrix K:" << std::endl;

    k.printMatrix();

    matrix s;

    s = w * 2 + k;

    std::cout << "Matrix S = W * 2 + K:" << std::endl;

    s.printMatrix();

    squareMatrix q = s;

    std::cout << "Matrix Q:" << std::endl;

    q.printMatrix();

    std::cout << "det(Q)=" << q.determinant() << std::endl;

    system("pause");

    return 0;

    }


    написать администратору сайта