Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.11.2021, 00:11   #1
Alexandrietz
Пользователь
 
Регистрация: 30.11.2017
Сообщений: 15
По умолчанию Проблема с перегрузкой дружественных операторов.

Моя задача состоит в том, что мне требуется перегрузить дружественные(те, которые, конечно, могут ими быть)) операторы "[][]", "=", "+", "*", "-", "<=", ">=", "+="(прибавление ко всем элементам матрицы какого-то числа), но у меня возникает проблема с "=" и "+=". Предоставляю код.

Заголовочный файл
Код:
#include <fstream>
#include <iostream>

class Matrix
{
    public:
        double** matrix;                                // матрица
        int rows;                                       // количество строк
        int cols;                                       // количество столбцов

        Matrix(int rows_0, int cols_0);
        Matrix(Matrix& A, double increase);
        Matrix(double x);

        int GetRows();
        int GetCols();
        static Matrix ConvertToMatrix(double x);
        void InitiliazeMatrix(std::ifstream& f);
        double ConvertToDouble();
        void ShowMatrix();

        double* operator[](int index);
        friend Matrix operator+(Matrix& A, Matrix& B);
        friend Matrix operator-(Matrix& A, Matrix& B);
        friend Matrix operator*(Matrix& A, Matrix& B);
        const Matrix operator=(const Matrix& A);
        friend Matrix operator+=(Matrix& A, double a);
        friend bool operator<=(Matrix& A, Matrix& B);
        friend bool operator>=(Matrix& A, Matrix& B);

        ~Matrix();
};
Файл с реализацией
Код:
#include "Matrix.h"
#include <fstream>
#include <iostream>
#include <cstdlib>

using namespace std;

Matrix::Matrix(int rows_0 = 0, int cols_0 = 0)
{
    matrix = (double**) new double* [rows_0];
    for (int i = 0; i < rows_0; i++)
    {
        matrix[i] = (double*) new double[cols_0];
    }

    rows = rows_0;
    cols = cols_0;
}

Matrix::Matrix(Matrix& A, double increase = 0.0)
{
    if (A.GetCols() != 0 && A.GetRows() != 0)
    {
        matrix = (double**) new double* [A.rows];
        for (int i = 0; i < A.rows; i++)
        {
            matrix[i] = (double*) new double[A.cols];
        }
        for (int i = 0; i < A.rows; i++)
        {
            for (int j = 0; j < A.cols; j++)
            {
                matrix[i][j] = A.matrix[i][j] + increase;
            }
        }

        rows = A.rows;
        cols = A.cols;
    }
}

Matrix::Matrix(double x)
{
    matrix = (double**)new double* [1];
    matrix[0] = (double*)new double [1];
    matrix[0][0] = x;
    rows = 1;
    cols = 1;
}

int Matrix::GetRows()
{
    return (*this).rows;
}

int Matrix::GetCols()
{
    return (*this).cols;
}

Matrix Matrix::ConvertToMatrix(double x)
{
    return Matrix(x);
}


void Matrix::InitiliazeMatrix(ifstream& f)
{
    for (int i = 0; i < (*this).rows; i++)
    {
        for (int j = 0; j < (*this).cols; j++)
        {
            f >> (*this).matrix[i][j];
        }
    }
}

double Matrix::ConvertToDouble()
{
    double s = 0.0;

    for (int i = 0; i < (*this).rows; i++)
    {
        for (int j = 0; j < (*this).cols; j++)
        {
            s += (*this).matrix[i][j];
        }
    }
    double size = static_cast<double>((*this).rows) * static_cast<double>((*this).cols);

    return s / size;
}

void Matrix::ShowMatrix()
{
    for (int i = 0; i < (*this).rows; i++)
    {
        for (int j = 0; j < (*this).cols; j++)
        {
            cout << (*this).matrix[i][j] << " ";
        }
        cout << endl;
    }
    cout << endl;
}

double* Matrix::operator[](int index)
{
    int max_index = (*this).rows > (*this).cols ? (*this).rows - 1 : (*this).cols - 1;

    if (index < 0 || index > max_index)
    {
        cout << "Индекс вне границ." << endl;
        return nullptr;
    }
 
    return (*this).matrix[index];
}

const Matrix Matrix::operator=(const Matrix& A)
{
    if (&A != nullptr)
    {
        if ((*this).rows == A.rows && (*this).cols == A.cols)
        {
            for (int i = 0; i < (*this).rows; i++)
            {
                for (int j = 0; j < (*this).cols; j++)
                {
                    (*this).matrix[i][j] = A.matrix[i][j];
                }
            }
        }
    }

    return *this;
}

Matrix operator+(Matrix& A, Matrix& B)
{
    if (A.rows == B.rows && A.cols == B.cols)
    {
        Matrix W(A);
        for (int i = 0; i < W.rows; i++)
        {
            for (int j = 0; j < W.cols; j++)
            {
                W.matrix[i][j] += B.matrix[i][j];
            }
        }
        return Matrix(W);
    }
    else
    {
        cout << "Размеры матриц не удовлетворяют сложению." << endl;
        exit(1);
    }
}

Matrix operator-(Matrix& A, Matrix& B)
{
    if (A.rows == B.rows && A.cols == B.cols)
    {
        Matrix W(A);
        for (int i = 0; i < W.rows; i++)
        {
            for (int j = 0; j < W.cols; j++)
            {
                W.matrix[i][j] -= B.matrix[i][j];
            }
        }
        return Matrix(W);
    }
    else
    {
        cout << "Размеры матриц не удовлетворяют вычитанию." << endl;
        exit(1);
    }
}

Matrix operator*(Matrix& A, Matrix& B)
{
    if (A.cols == B.rows)
    {
        Matrix W(A.rows, B.cols);
        double mult = 0.0;
        for (int i = 0; i < A.rows; i++)
        {
            for (int j = 0; j < B.cols; j++)
            {
                for (int k = 0; k < A.cols; k++)
                {
                    mult += (A.matrix[i][k] * B.matrix[k][j]);       // Определение умножения матриц из линейой алгебры
                }
                W.matrix[i][j] = mult;
                mult = 0.0;
            }
        }
        
        return Matrix(W);
    }
    else
    {
        cout << "Размер матриц не подходит для их перемножения." << endl;
        exit(1);
    }
}

Matrix operator+=(Matrix& A, double a)
{
    if (&A != nullptr)
    {
        Matrix W(A);
        for (int i = 0; i < W.rows; i++)
        {
            for (int j = 0; j < W.cols; j++)
            {
                W.matrix[i][j] += a;
            }
        }
        return(W);
    }

    return Matrix();
}

bool operator<=(Matrix& A, Matrix& B)
{
    if (A.rows == B.rows && A.cols == B.cols)
    {
        for (int i = 0; i < A.rows; i++)
        {
            for (int j = 0; j < B.cols; j++)
            {
                if (A.matrix[i][j] > B.matrix[i][j])
                {
                    return false;
                }
            }
        }
    }

    return true;
}

bool operator>=(Matrix& A, Matrix& B)
{
    if (A.rows == B.rows && A.cols == B.cols)
    {
        for (int i = 0; i < A.rows; i++)
        {
            for (int j = 0; j < B.cols; j++)
            {
                if (A.matrix[i][j] < B.matrix[i][j])
                {
                    return false;
                }
            }
        }
    }

    return true;
}


Matrix::~Matrix()
{
    if ((*this).cols > 0)
    {
        for (int i = 0; i < (*this).rows; i++) { delete[](*this).matrix[i]; }
    }

    if ((*this).rows > 0) { delete[](*this).matrix; }
}
Проблема возникает в том, что не работает "+=", то есть прибавление double-числа ко всем элементам матрицы. В добавок, когда деструктор начинает удалять матрицы, то вызывается исключение. Помогите, пожалуйста.
Изображения
Тип файла: png Screenshot_1.png (8.7 Кб, 1 просмотров)
Тип файла: jpg Screenshot_2.jpg (35.0 Кб, 1 просмотров)
Alexandrietz вне форума Ответить с цитированием
Старый 30.11.2021, 00:11   #2
Alexandrietz
Пользователь
 
Регистрация: 30.11.2017
Сообщений: 15
По умолчанию

Вот главный файл
Код:
/*
Операции «+», «-» и «*», созданные при выполнении задания «Перегрузка операций», реализовать как дружественные функции. В программе, 
использующей разработанный класс, привести примеры выражений, который не могли быть реализованы, когда эти операции были функциями-членами 
класса.
*/

#include <locale.h>
#include <fstream>
#include <iostream>
#include <cstdio>
#include "Matrix.h"

#define _CRT_SECURE_NO_WARNINGS

using namespace std;

int main(int argc, char* argv[])
{
	ifstream f("f.txt");
	int rows, cols;
	double x, increase, a;

	setlocale(LC_ALL, "Rus");

	if (argc < 1)
	{
		cout << "Недостаточно аргументов командной строки." << endl;
		return 0;
	}

	if (f.bad())
	{
		cout << "Файла не существует в директории проекта." << endl;
		return 0;
	}
	else
	{
		if (!f.is_open()) { cout << "Файл не открывается." << endl; return 0; }
		else if (f.peek() == EOF) { cout << "Файл пуст." << endl; return 0; }
		else
		{
			f >> x;
			f >> rows;
			f >> cols;
			if (rows <= 0 || cols <= 0)
			{
				cout << "Размеры матрицы не могут быть неположительными." << endl;
				return 0;
			}
			else
			{
				Matrix A(rows, cols);
				A.Matrix::InitiliazeMatrix(f);
				f.close();
				cout << "A:" << endl;
				A.Matrix::ShowMatrix();

				cout << "Ввести значение increase: ";
				cin >> increase;
				cout << endl;
				Matrix B(A, increase);
				cout << "B: " << endl;
				B.Matrix::ShowMatrix();

				bool ab = A <= B;
				cout << "A <= B: " << boolalpha << ab << endl;
				cout << endl;

				Matrix one_on_one_matrix = Matrix::ConvertToMatrix(x);
				cout << "Матрица 1 на 1: ";
				one_on_one_matrix.Matrix::ShowMatrix();

				double average = B.Matrix::ConvertToDouble();
				cout << "Среднее значение элементов матрицы: " << average << endl;
				cout << endl;

				Matrix C(A);
				C = A + B;
				cout << "C = A + B:" << endl;
				C.Matrix::ShowMatrix();

				C = A - B;
				cout << "C = A - B:" << endl;
				C.Matrix::ShowMatrix();

				Matrix D(A.rows, B.cols);
				D = B * B;
				cout << "D = B * B:" << endl;
				D.Matrix::ShowMatrix();

				bool ac = A <= C;
				cout << "A <= C: " << boolalpha << ac << endl;
				cout << endl;

				cout << "Ввести значение(a), на которое изменятся все элементы матрицы: ";
				cin >> a;
				cout << endl;

				Matrix E(A);
				E += a;
				cout << "E + a:" << endl;
				E.Matrix::ShowMatrix();
				cout << endl;
			}
		}
	}

	return 0;
}
И почему мой конструктор копирования возвращает ссылку на оригинал, а не полноценную независимую от оригинала копию?

Последний раз редактировалось Alexandrietz; 30.11.2021 в 03:20.
Alexandrietz вне форума Ответить с цитированием
Старый 30.11.2021, 05:29   #3
Алексей1153
фрилансер
Форумчанин
 
Регистрация: 11.10.2019
Сообщений: 947
По умолчанию

Цитата:
Сообщение от Alexandrietz Посмотреть сообщение
friend Matrix operator+(Matrix& A, Matrix& B);
friend Matrix operator-(Matrix& A, Matrix& B);
friend Matrix operator*(Matrix& A, Matrix& B);
это - глобальные функции, поэтому при реализации не нужно указывать область Matrix::


Цитата:
Сообщение от Alexandrietz Посмотреть сообщение
friend Matrix operator+=(Matrix& A, double a);
friend bool operator<=(Matrix& A, Matrix& B);
friend bool operator>=(Matrix& A, Matrix& B);
а эти не нужно делать глобальными


Цитата:
Сообщение от Alexandrietz Посмотреть сообщение
const Matrix operator=(const Matrix& A);
этот оператор должен возвращать неконстантную ссылку, а не экземпляр

Цитата:
Сообщение от Alexandrietz Посмотреть сообщение
Matrix(Matrix& A, double increase);
ссылка в аргументах должна быть константной


Цитата:
Сообщение от Alexandrietz Посмотреть сообщение
const Matrix Matrix:: operator= (const Matrix& A)
{
if (&A != nullptr)
это условие всегда выполнится. Зачем оно?

Последний раз редактировалось Алексей1153; 30.11.2021 в 05:33.
Алексей1153 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не понятная ошибка с перегрузкой операторов RaTeN Общие вопросы C/C++ 3 10.03.2012 16:09
Проблема с перегрузкой операторов Furchtlos Общие вопросы C/C++ 26 28.12.2011 01:39
Проблема с перегрузкой операторов в C++ StudentofSUSU Помощь студентам 2 30.09.2010 10:04
Проблема с перегрузкой операторов, не могу разобраться mrLee Помощь студентам 1 30.01.2010 00:23
Проблема с перегрузкой операторов, не могу разобраться mrLee Общие вопросы C/C++ 0 29.01.2010 18:45