Класс матрица

Класс матрица

Нужно сделать класс — матрица. Он должен содержать методы ввода-вывода, присвоение значения элементу, умножения на другую матрицу, сложение с другой матрицей.

Вот мой код решения задачи:



#include <iostream>

using namespace std;

inline int min ( int, int );

class matrix
{
    protected:
        int **mat;
        int n,m;
    public:
        matrix( int i, int i2 ): n(i), m(i2)
        {
            mat = new int*[n];
            for ( int i = 0; i < m; i++ )
            {
                mat[i] = new int[m];
            }
            cout << "Создана матрица размером " << n << " на " << m <<" элементов."<<endl;
        }
        void get()
        {
            for ( int i = 0; i < n; i++ )
                for ( int j = 0; j < m; j++ )
                    cin >> mat[i][j];                   
        }
        void display() const
        {
            for ( int i = 0; i < n; i++ )
                for ( int j = 0; j < m; j++ )
                {
                    if ( j % 5 == 0 ) cout << endl;
                    cout << mat[i][j] << " ";
                }
        }
        void summ_matrix ( matrix some )
        {
            for ( int i = 0; i < min(n, some.n); i++ )
                for ( int j = 0; j < min(m, some.m); j++ )
                    mat[i][j] += some.mat[i][j];
        }
        void multi_matrix ( matrix some )
        {
            for ( int i = 0; i < min (n, some.n); i++ )
                for ( int j = 0; j < min(m, some.m); j++ )
                    mat[i][j] *= some.mat[i][j];
        }
        int& operator[][](int i, int i2)
        {
            return mat[i][i2];
        }
        ~matrix()
        {
            for ( int i = 0; i < n; i++ )
            {
                delete []mat[i];
            }
            cout << "Матрица удалена!" << endl;
        }
};

int main( int argv, char *argc[] )
{
    setlocale ( 0, "Russian" );
    return 0;
}

inline int min( int a, int b )
{
    return ( a <= b )? a : b;
}



компилятор кроет матом вот это:



 int& operator[][](int i, int i2)
        {
            return mat[i][i2];
        }

со словами:
[Error] declaration of 'operator[]' as non-function
[Error] expected ';' at end of member declaration

я понял это как запрет на перегрузку [ ][ ], но Лафоре не упоминал эту операцию в списке запрещённых к перегрузке. В чём дело?

Оператора [][] в С++ не существует. Есть только оператор []. Перегружать можно только существующие операторы.

Некоторые замечания по программе и советы, если, конечно, интересно ))

(0) Создать действительно полезный класс, реализующий матрицу и матричные вычисления — нетривиальная задача. Но дорогу осилит идущий.

Далее по порядку уменьшения значимости: от критичных к рекомендуемым.

(1) В деструкторе не полностью освобождается память. После цикла удаления массивов (строк) надо добавить удаление массива указателей на эти строки, т.е. delete [] mat;. Сравни с тем, как ты занимаешь память в конструкторе.

(2) Как тебе уже сказал компилятор, доступ к элементам матрицы надо делать не через перегрузку оператора, а через функцию вида int & elem(int row, int col) {...}.

(3) В функции display() строка if ( j % 5 == 0 ) cout << endl; видимо подразумевает всегда 5 элементов в строке матрицы, что не всегда соответствует действительности.

(4) Сложение и умножение матриц реализовано по-варварски. По крайней мере, сложение и умножение матриц в твоём понимании расходится с общепринятым. См. Операции над матрицами (Википедия).

(5) Как правило (зависит от компилятора), если функция имеет тело (код) в описании класса, то для такой функции компилятором неявно применяется спецификатор inline. Что во многих случаях не есть хорошо. Поэтому реализацию методов класса надо вынести из описания класса, а по хорошему, твою программу необходимо разделить на три файла: (а) головная программа, (б) header-файл с описанием класса и (в) cpp-файл с реализацией методов класса. Как всё это подключать, надеюсь, знаешь.

(6) Вместо функций get() и display() я бы посоветовал переопределить операторы >> и << для потокового ввода/вывода. В таком виде для ввода или вывода матрицы можно легко использовать как cin/cout, так и любые другие потоки ввода/вывода (напр. файловые).

(7) Для сложения и умножения матриц лучше использовать дружественные функции (friend) или перегрузку операторов (тоже как дружественные функции).

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

Спасибо, Череп!(строго не судите я школьник(8 класс) и просто не знал некоторых моментов, о которых вы говорили)

Учись, школьник, у тебя это получается лучше, чем у многих обитателей этого ресурса.

Помимо Лафоре, я бы ещё посоветовал обзавестись:

  1. Герберт Шилдт. Полный справочник по С++. Некоторые аспекты изложены шире, чем у Лафоре. Но читать, наверное, посложнее.
  2. Николай Джосьютис. С++ Стандартная библиотека. Можно использовать как справочник по STL.

Конечно, этими двумя книгами класс must have не ограничивается ))

Почему бы не реализовать класс для работы с массивами (аля std::vector)? А в случае с матрицей, мы просто создаем массив из массивов.

Но делать это стоит только ради обучения. На практике обычно используют вышеупомянутый std::vector.

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

Вообще, работа через операторы [] более явная и очевидная для пользователя.

Тут я бы сделал просто перегрузку оператора [], который бы возвращал другой объект, например matr_elem, у которого также был бы перегружен оператор [].

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

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

Пожалуйста, оформляйте исходный код в соответствии с правилами разметки. Для того, чтобы вставить код в комментарий, скопируйте его в текстовое поле ниже, после чего выделите то, что скопировали и нажмите кнопку «код» в панели инструментов. Иначе ваш код может принять нечитаемый вид.

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.