PDA

Показать полную графическую версию : Матрицы - перегрузка оператора - operator[][]


котвася
29-07-2010, 19:32
я на много медленнее это делаю, просто хобби. А без хобби на куда, т.к это одно из составляющих счастья :)

это не пример конечно, а мое искусство :)
хотелось бы узнать в каком месте я за рычаг потянул?
надо было перегрузить operator[][] << >> для матриц.

криворукий код:

//MAIN.CPP
//Перегрузка операций

#include <iostream>

using std::cin;
using std::cout;
using std::endl;
using std::ostream;
using std::istream;

#include <iomanip>

using std::setw;

//Определение класса Matrix

class Matrix
{
friend ostream &operator<< (ostream &, const Matrix &);
friend istream &operator>> (istream &, Matrix &);
public:
Matrix(int, int);
~Matrix();
int &operator[](int);
private:
int const line;
int const column;
int *mPtr;
};

Matrix::Matrix(int l, int c)
:line(l), column(c)
{
mPtr = new int[line+1][column+1];
}

Matrix::~Matrix()
{
delete [] mPtr;
}

ostream &operator<< (ostream &output, const Matrix &m)
{
for(int i = 0; i < m.line; i++)
for(int j = 0; j < m.column; j++)
output << m[i][j] << endl;
return output;
}

istream &operator>> (istream &input, Matrix &m)
{
for(int i = 0; i < m.line; i++)
for(int j = 0; j < m.column; j++)
input >> setw(1) >> m[i][j];
return input;
}

int &Matrix::operator[][] (int Line, int Column)
{
return ((Line >= 0 && Column >= 0 && Line < line && Column < column) ? mPtr[Line][Column] : mPtr[0][0]);
}

int main()
{
setlocale(LC_ALL, ".1251");
cout << "Введите размер матрицы(строка х столбец)" << endl;
int line, column;

cin >> line >> column;

Matrix matrix(line, column);

cout << "Введите значения матрицы:" << endl;

cin >> matrix;

cout << "Вы ввели: " << endl << matrix;

system("pause");

return 0;
}


1>------ Построение начато: проект: Упражнение_на_перегрузку_операций, Конфигурация: Debug Win32 ------
1>Компиляция...
1>main.cpp
1>c:\$p\mvs\{как программировать на с++}\упражнение_на_перегрузку_операций\упражнение_на_перегрузку_операций\main.cpp(35) : error C2540: неконстантное выражение используется в качестве границы массива
1>c:\$p\mvs\{как программировать на с++}\упражнение_на_перегрузку_операций\упражнение_на_перегрузку_операций\main.cpp(35) : error C2440: =: невозможно преобразовать 'int (*)[1]' в 'int *'
1> Типы, на которые указывают указатели, не связаны; для преобразования требуется reinterpret_cast, приведение в стиле С или приведение в стиле функции
1>c:\$p\mvs\{как программировать на с++}\упражнение_на_перегрузку_операций\упражнение_на_перегрузку_операций\main.cpp(45) : error C2059: синтаксическая ошибка: ]
1>c:\$p\mvs\{как программировать на с++}\упражнение_на_перегрузку_операций\упражнение_на_перегрузку_операций\main.cpp(52) : error C2678: бинарный '[': не найден оператор, принимающий левый операнд типа 'const Matrix' (или приемлемое преобразование отсутствует)
1> c:\$p\mvs\{как программировать на с++}\упражнение_на_перегрузку_операций\упражнение_на_перегрузку_операций\main.cpp(25): может быть 'int &Matrix::operator [](int)'
1> при попытке сопоставить список аргументов '(const Matrix, int)'
1>c:\$p\mvs\{как программировать на с++}\упражнение_на_перегрузку_операций\упражнение_на_перегрузку_операций\main.cpp(60) : error C2109: для индекса требуется массив или указатель
1>Журнал построения был сохранен в "file://c:\$p\mvs\{как программировать на с++}\Упражнение_на_перегрузку_операций\Упражнение_на_перегрузку_операций\Debug\BuildLog.htm"
1>Упражнение_на_перегрузку_операций - ошибок 5, предупреждений 0
========== Построение: успешно: 0, с ошибками: 1, без изменений: 0, пропущено: 0 ==========

котвася
29-07-2010, 20:51
часть сам уже сделал:

//MAIN.CPP
//Перегрузка операций

#include <iostream>

using std::cin;
using std::cout;
using std::endl;
using std::ostream;
using std::istream;

#include <iomanip>

using std::setw;

//Определение класса Matrix

class Matrix
{
friend ostream &operator<< (ostream &, const Matrix &);
public:
Matrix(int, int);
~Matrix();
private:
int ROW;
int COLUMN;
int **matrixPtr;
int *linePtr;
};


//----------------------------------------------------------------

Matrix::~Matrix()
{
for(int i = 0; i < ROW; i++)
delete [] matrixPtr[i];
delete [] matrixPtr;
}

//----------------------------------------------------------------

ostream &operator<< (ostream &out, const Matrix &M)
{
for(int i= 0; i <M.ROW; i++)
{
for(int j = 0; j < M.COLUMN; j++)
out << *(M.matrixPtr[i]+j);
out << endl;
}
return out;
}

//---------------------------------------------------------------

Matrix::Matrix(int row, int column)
{
ROW = row;
COLUMN = column;
matrixPtr = new int*[ROW];
for(int i = 0; i < ROW; i++)
{
matrixPtr[i] = new int[COLUMN];
for(int j = 0; j < COLUMN; j++)
*(matrixPtr[i] + j) = j;
}
}
int main()
{
setlocale(LC_ALL, ".1251");
cout << "Введите размер матрицы(строка х столбец)" << endl;
Matrix matrix(5, 6);

cout << matrix << endl;

system("pause");
return 0;
}



осталось [][] кто поможет?
Мне кажется, что надо [] последовательно перегрузить. А?

котвася
29-07-2010, 22:51
Я решил все сам, ток не могу понять как оно работает:

//MAIN.CPP
//Перегрузка операций

#include <iostream>

using std::cin;
using std::cout;
using std::endl;
using std::ostream;
using std::istream;

#include <iomanip>

using std::setw;

//Определение класса Matrix

class Matrix
{
friend ostream &operator<< (ostream &, const Matrix &);
public:
int *operator[](int);
Matrix(int, int);
~Matrix();
private:
int ROW;
int COLUMN;
int **matrixPtr;
int *linePtr;
};

//----------------------------------------------------------------

int *Matrix::operator[] (int number)
{
return matrixPtr[number];
}

//----------------------------------------------------------------

Matrix::~Matrix()
{
for(int i = 0; i < ROW; i++)
delete [] matrixPtr[i];
delete [] matrixPtr;
}

//----------------------------------------------------------------

ostream &operator<< (ostream &out, const Matrix &M)
{
for(int i= 0; i <M.ROW; i++)
{
for(int j = 0; j < M.COLUMN; j++)
out << setw(4) << *(M.matrixPtr[i]+j) << ' ';
out << endl;
}
return out;
}

//---------------------------------------------------------------

Matrix::Matrix(int row, int column)
{
ROW = row;
COLUMN = column;
matrixPtr = new int*[ROW];
for(int i = 0; i < ROW; i++)
{
matrixPtr[i] = new int[COLUMN];
for(int j = 0; j < COLUMN; j++)
*(matrixPtr[i] + j) = j*i;
}
}
int main()
{
int m[2][3];
setlocale(LC_ALL, ".1251");
cout << "Введите размер матрицы(строк -> столбцов)" << endl;
int row, column;
cin >> row >> column;
Matrix matrix(row, column);
cout << matrix << endl;
cout << "Введите индекс ячейки(стока -> столбец)" << endl;
cin >> row >> column;
cout << "matrix[" << row << "][" << column << "]= " << matrix[row][column] << endl;

system("pause");
return 0;
}

котвася
29-07-2010, 23:15
Остался один вопрос.
Как сделать так, что бы вместо

matrix[row][column]

писать

matrix[row, column] ???

Drongo
30-07-2010, 14:17
котвася, Это надо кажется перегружать () - operator()

Тогда будет формироватья matrix(row, column);

pva
30-07-2010, 19:35
вариантов как всегда море:
1)

struct index
{
int col, row;
index(int c, int r) : col(c), row(r) {}
};

const double& Matrix::operator[](index i) {...}
...

// используем:
double d = matrix[index(1,1)];

2)

class Row
{
public:
double operator[](int col) {return owner->cell(row, col);}
Row(Matrix& m, int i) : owner(&m), index(i) {}
private:
int index;
Matrix* owner;
};

class Matrix
{
public:
Row operator[](int row) {return Row(this,row);}
const double& cell(int row, int col);
};

// пользуем:
double d = matrix[row][col];

котвася
31-07-2010, 00:04
Как понял надо сделать так:

//MAIN.CPP
//Перегрузка операций

#include <iostream>

using std::cin;
using std::cout;
using std::endl;
using std::ostream;
using std::istream;

#include <iomanip>

using std::setw;



struct index
{
int _COLUMN, _ROW;
index(int row, int column) :_ROW(row), _COLUMN(column) {}
};


//Определение класса Matrix
class Matrix
{
friend ostream &operator<< (ostream &, const Matrix &);
public:
int &operator[](int);
int &operator[](index);
Matrix(int, int);
~Matrix();
private:
int ROW;
int COLUMN;
int **matrixPtr;
int *linePtr;
};

int &Matrix::operator[](index i)
{
return *matrixPtr[i._ROW, i._COLUMN];
}

//----------------------------------------------------------------

int &Matrix::operator[] (int number)
{
return *matrixPtr[number];
}

//----------------------------------------------------------------

Matrix::~Matrix()
{
for(int i = 0; i < ROW; i++)
delete [] matrixPtr[i];
delete [] matrixPtr;
}

//----------------------------------------------------------------

ostream &operator<< (ostream &out, const Matrix &M)
{
for(int i= 0; i <M.ROW; i++)
{
for(int j = 0; j < M.COLUMN; j++)
out << setw(4) << *(M.matrixPtr[i]+j) << ' ';
out << endl;
}
return out;
}

//---------------------------------------------------------------

Matrix::Matrix(int row, int column)
{
ROW = row;
COLUMN = column;
matrixPtr = new int*[ROW];
for(int i = 0; i < ROW; i++)
{
matrixPtr[i] = new int[COLUMN];
for(int j = 0; j < COLUMN; j++)
*(matrixPtr[i] + j) = j*i;
}
}
int main()
{
setlocale(LC_ALL, ".1251");
cout << "Введите размер матрицы(строк -> столбцов)" << endl;
int row, column;
cin >> row >> column;
Matrix matrix(row, column);
cout << matrix << endl;
cout << "Введите индекс ячейки(стока -> столбец)" << endl;
cin >> row >> column;
//cout << "matrix[" << row << "][" << column << "]= " << matrix[row][column] << endl;
cout << "matrix[" << row << "," << column << "]= " << matrix[row,column] << endl;
cout << endl;

system("pause");
return 0;
}


только вот не правильно работает :(

pva
31-07-2010, 21:07
int &Matrix::operator[](index i) { return *matrixPtr[i._ROW, i._COLUMN]; } »
это чего такое? оно собирается?

// примерно так должно быть
return *matrixPtr[i._ROW*COLUMN + i._COLUMN];

котвася
31-07-2010, 22:07
собирается, чего тут удивительного?

pva
31-07-2010, 23:47
я думал в c/c++ нет конструкции [a, b] (т.е. вызова оператора [] с двумя аргументами)

котвася
31-07-2010, 23:48
не ну работает, только не правильно)

pva
01-08-2010, 14:53
Откомпилировал, сначала долго удивлялся, но потом вспомнил про оператор ",". Смысл в следующем: все выражения должны приводиться к первому, стоящему перед первой запятой. Результатом оказывается последний (после последней запятой). Например:

int i = (1,2,3);
// i = 3;

здесь получилось что в скомках как раз и стоит оператор ",", поэтому m[a,b] = m[b], И конечно работает неправильно. А чтобы работало правильно, нужно вызывать m[index(a,b)]

Drongo
01-08-2010, 18:50
я думал в c/c++ нет конструкции [a, b] (т.е. вызова оператора [] с двумя аргументами) »А я это помнил. :)
котвася, Это надо кажется перегружать () - operator()
Тогда будет формироватья matrix(row, column); »




© OSzone.net 2001-2012