- Автор темы
- #1
Практический пример. Класс матрица.
В этом разделе рассматривается пример на перегрузку операторов.
Домашнее задание
Создать проект, в котором реализуются следующие классы: "Сотрудник", "Фирма". Соответственно, "Фирма" состоит из списка сотрудников, который может изменяться (количество и внутреннее содержимое). Необходимо реализовать следующие возможности: распечатки списка сотрудников при помощи оператора foreach, сравнение сотрудников между собой по должности (продумать возможность хранения табели о рангах), перегрузка операторов + и - для добавления и удаления
В этом разделе рассматривается пример на перегрузку операторов.
Код:
// CSharpMatrix.cs
using System;
namespace CSharpApplication.ClassMatrixSample
{
class Matrix
{
// Матрица
int [,] mtr = null;
// Размерности
int M = 0, N = 0;
// Свойство, возвращающее первую размерность
public int FirstDimension
{
get
{
return M;
}
}
// Свойство, возвращающее вторую размерность
public int SecondDimension
{
get
{
return N;
}
}
// Проверка на пустой объект
public bool IsEmpty
{
get
{
return mtr == null;
}
}
// Конструктор по умолчанию
public Matrix()
{
// Создан для удобства работы
}
// Конструктор для создания матрицы произвольного вида
public Matrix(int M, int N)
{
if(M <= 0 || N <= 0)
return;
this.M = M;
this.N = N;
mtr = new int[M, N];
}
// Аналог конструктора копирования
public Matrix(Matrix m)
{
M = m.M;
N = m.N;
// Функция Clone() класса Array осуществляет
// поверхностное копирование массива
mtr = (int[,])m.mtr.Clone();
}
// Конструктор для создания объекта на основе массива
public Matrix(int [,] m)
{
// Определение размерностей переданного массива
M = m.GetLength(0);
N = m.GetLength(1);
mtr = (int[,])m.Clone();
}
// Создание копии массива (вместо оператора присваивания)
public Matrix Copy()
{
// Вызов конструктора копирования
return new Matrix(this);
}
// Индексатор для доступа к элементам матрицы
public int this [int i, int j]
{
// Получение элемента с проверкой границ
get
{
if(i < 0 || i >= M || j < 0 || j >= N)
throw new IndexOutOfRangeException();
return mtr[i, j];
}
// Установка нового значения элемента с проверкой границ
set
{
if(i < 0 || i >= M || j < 0 || j >= N)
throw new IndexOutOfRangeException();
mtr[i, j] = value;
}
}
// Перегруженный оператор + для сложения двух матриц
public static Matrix operator + (Matrix m1, Matrix m2)
{
// В случае ошибки возвращаем пустой объект
if(m1.M != m2.M || m1.N != m2.N)
return new Matrix();
// Сложение матриц
Matrix Result = new Matrix(m1);
for(int i = 0; i < Result.M; i++)
{
for(int j = 0; j < Result.N; j++)
{
Result.mtr[i, j] += m2.mtr[i, j];
}
}
return Result;
}
// Перегруженный оператор * для произведения двух матриц
public static Matrix operator * (Matrix m1, Matrix m2)
{
// В случае ошибки возвращаем пустой объект
if(m1.N != m2.M)
return new Matrix();
// Произведение матриц
Matrix Result = new Matrix(m1.M, m2.N);
for(int i = 0; i < m1.M; i++)
{
for(int j = 0; j < m2.N; j++)
{
for(int k = 0; k < m1.N; k++)
{
Result.mtr[i, j] += m1.mtr[i, k] * m2.mtr[k, j];
}
}
}
return Result;
}
// Перегруженный оператор + для сложения матрицы с числом
public static Matrix operator + (Matrix m1, int value)
{
Matrix Result = new Matrix(m1);
for(int i = 0; i < Result.M; i++)
{
for(int j = 0; j < Result.N; j++)
{
Result.mtr[i, j] += value;
}
}
return Result;
}
// Перегруженный оператор * для произведения матрицы на число
public static Matrix operator * (Matrix m1, int value)
{
Matrix Result = new Matrix(m1);
for(int i = 0; i < m1.M; i++)
{
for(int j = 0; j < m1.N; j++)
{
Result.mtr[i, j] *= value;
}
}
return Result;
}
// Проверка на неравенство матриц (по элементам)
public static bool operator != (Matrix m1, Matrix m2)
{
if(m1.M != m2.M || m1.N != m2.N)
return true;
for(int i = 0; i < m1.M; i++)
{
for(int j = 0; j < m1.N; j++)
{
if(m1.mtr[i, j] != m2.mtr[i, j])
return true;
}
}
return false;
}
// Проверка на равенство матриц (по элементам)
public static bool operator == (Matrix m1, Matrix m2)
{
return !(m1 != m2);
}
// Переопределение унаследованной (неявно от класса Object)
// функции Equals для проверки равенства объектов
public override bool Equals(object obj)
{
try
{
return (bool) (this == (Matrix) obj);
}
catch
{
// Если obj не принадлежит классу Matrix
return false;
}
}
// Переопределение унаследованной (неявно от класса Object)
// функции GetHashCode для возврата хэш-кода объекта
public override int GetHashCode()
{
// Не самый удачный вариант
return M ^ N;
}
// Вывод матрицы на экран
public void Print()
{
string s = new string('-', 79);
Console.WriteLine(s);
for(int i = 0; i < M; i++)
{
for(int j = 0; j < N; j++)
{
Console.Write("{0,5}", mtr[i, j]);
}
Console.WriteLine();
}
Console.WriteLine(s);
}
}
}
// User.cs
using System;
using CSharpApplication.ClassMatrixSample;
namespace CSharpApplication.ClassTestSample
{
class Test
{
// Тестирование возможностей класса
static void Main()
{
int [,] a = new int[,] {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
Matrix m = new Matrix(a);
Console.WriteLine("m");
m.Print();
Matrix m1 = new Matrix(m);
Console.WriteLine("m1");
m1.Print();
Matrix m2 = m1.Copy();
Console.WriteLine("m2");
m2.Print();
m1 += m2 * 2;
Console.WriteLine("m1");
if(m1.IsEmpty)
{
Console.WriteLine("Empty object!!!");
}
else
{
m1.Print();
}
Matrix m3 = new Matrix();
m3 *= m3;
Console.WriteLine("m3");
if(!m3.IsEmpty)
{
m3.Print();
}
else
{
Console.WriteLine("Empty object!!!");
}
if(m1 == m2)
Console.WriteLine("Equal");
else
Console.WriteLine("Not Equal");
}
}
}
Домашнее задание
Создать проект, в котором реализуются следующие классы: "Сотрудник", "Фирма". Соответственно, "Фирма" состоит из списка сотрудников, который может изменяться (количество и внутреннее содержимое). Необходимо реализовать следующие возможности: распечатки списка сотрудников при помощи оператора foreach, сравнение сотрудников между собой по должности (продумать возможность хранения табели о рангах), перегрузка операторов + и - для добавления и удаления