Перегрузка унарных операций. #include <iostream>

#include <iostream>

using namespace std;

class TA{

int a;

int b;

public:

TA (int x=3,int y=4){a=x;b=y;}

friend void print(TA&);

//перегрузка унарной операции

/*Унарная функция-операция, определяемая внутри класса, должна быть представлена с помощью нестатического метода без параметров, при этом операндом является вызвавший ее объект, например:

*/

TA& operator++(){a++;b++;return *this;}

//перегрузка бинарной операции : вызывающий объект считается первым операндом

const TA& operator=(const TA& operand2)

{if(&operand2==this) return *this;

//если класс содержит динамический массив необходимо удалить

//занимаемую память и выделить новую память нужного размера

//затем скопировать все элементы класса аналогично конструктору копирования

a=operand2.a;b=operand2.b;

}

TA operator+(TA& operand2){

TA sum;

sum.a=a+operand2.a;

sum.b=b+operand2.b;

return sum;

}

bool operator>(TA& operand2){

return (a>operand2.a&&b>operand2.b)? true: false;

}

//перегрузка потоков ввода вывода

//перегрузка потоков осуществляется только

//с помощью дружественных функций

friend ostream& operator<<(ostream& out,TA &obj)

{out<<"a= "<<obj.a<<"\tb="<<obj.b;

return out;}

friend istream& operator>>(istream& in,TA &obj)

{

cout<<"Vvedite a=";

in>>obj.a;

cout<<"Vvedite b=";

in>>obj.b;

return in;}

};

int main()

{

TA b(4,5),c(1,1);

print(b);

b++;

print(b);

TA s=b+c;

print(s);

if (s>b)cout<<">"<<endl;

cin>>s;

cout<<s<<endl;//a=6 b=7

cin.get();

cin.get();

retrun 0;

}

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

void print(TA &obj)

{cout<<obj.a<<"\t"<<obj.b<<endl;}

/*

Написать класс "Вектор"

Реализовать конструкторы по уполчанию, с параметром и коппирования

Релизовать в виде методов

- заполнения массива случайным образом;

- суммирование элементов массива

Перегрузить операции:

- сравнения (возвращает истину, если сумма элементов обоих операндов равна);

- присваивания;

- потоковые операции ввода (">>") вывода "<<".

Проиллюстрировать работу реализованных методов.

*/

#include "stdafx.h"

#include <iostream>

#include <time.h>

class Tvec

{

int *vec;

int n;

public:

Tvec();//конструктор по умолчанию

Tvec(int n);//конструктор с параметром

Tvec(Tvec &);//конструктор коппирования

~Tvec(){delete [] vec;}//деструктор

void Rand(int);//метод заполнения случайным образом от 0 до заданного параметра

int Sum();//метод суммирования элементов

bool operator==(Tvec&);//перегрузка операции "=="

Tvec& operator=(Tvec&);//перегрузка операции "="

Tvec operator+(Tvec&);//перегрузка операции "+"

//перегрузка потоков

friend std::istream& operator>>(std::istream&,Tvec&);

friend std::ostream& operator<<(std::ostream&,Tvec&);

};

int main()

{

Tvec vec1, vec2(10);

vec2.Rand(5);

vec1.Rand(10);

std::cout<<"Ischodnie dannie:"<<std::endl;

std::cout<<"vec1 = "<<vec1<<std::endl;

std::cout<<"vec2 = "<<vec2<<std::endl;

std::cout<<"Sum1 = "<<vec1.Sum()<<std::endl;

std::cout<<"Sum2 = "<<vec2.Sum()<<std::endl;

if( vec1==vec2) std::cout<<"vec1==vec2"<<std::endl;

else std::cout<<"vec1!=vec2"<<std::endl;

Tvec vec3(vec2);

if( vec3==vec2) std::cout<<"vec3==vec2"<<std::endl;

else std::cout<<"vec3!=vec2"<<std::endl;

vec1=vec2;

std::cout<<"Vec1 = "<<vec1<<std::endl;

vec3.Rand(8);

std::cout<<"Vec3 = "<<vec3<<std::endl;

std::cout<<"Vec1+Vec3 = "<<vec1+vec3<<std::endl;

std::cin.get();

return 0;

}

Tvec::Tvec()

{ this->n=5;

vec=new int[n];

}

Tvec::Tvec(int n=5)

{ this->n=n;

vec=new int[n];

}

Tvec::Tvec(Tvec &obj)

{this->n=obj.n; vec=new int[n];

for(int i(0);i<n;i++)

vec[i]=obj.vec[i];

};

void Tvec::Rand(int k)

{

srand(time(NULL));

for(int i(0);i<n;i++)

vec[i]=rand()%k;

}

int Tvec::Sum()

{

int S(0);

for(int i(0);i<n;i++)

S+=vec[i];

return S;

}

bool Tvec::operator==(Tvec& obj)

{

int S1=this->Sum();

int S2=obj.Sum();

return (S1==S2);

}

Tvec& Tvec::operator=(Tvec& obj)

{

if(this==&obj) return *this;

this->~Tvec();

n=obj.n;

vec=new int[n];

for(int i(0);i<n;i++)

vec[i]=obj.vec[i];

return *this;

}

Tvec Tvec::operator+(Tvec& obj)

{

int m=n+obj.n;

Tvec Merg(m);

int i(0);

for(;i<n;i++)

Merg.vec[i]=vec[i];

for(;i<m;i++)

Merg.vec[i]=obj.vec[i-n];

return Merg;

}

std::istream& operator>>(std::istream& in,Tvec& obj)

{

for(int i(0);i<obj.n;i++)

in>>obj.vec[i];

return in;

}

std::ostream& operator<<(std::ostream& out,Tvec& obj)

{

for(int i(0);i<obj.n;i++)

out<< obj.vec[i]<<" ";

out<<'\n';

return out;

}

Пример выполнения программы

Ischodnie dannie:

vec1 = 7 4 8 5 3

vec2 = 2 4 3 0 3 4 0 1 3 1

Sum1 = 27

Sum2 = 21

vec1!=vec2

vec3==vec2

Vec1 = 2 4 3 0 3 4 0 1 3 1

Vec3 = 1 0 4 1 1 7 1 7 4 3

Vec1+Vec3 = 2 4 3 0 3 4 0 1 3 1 1 0 4 1 1 7 1 7 4 3

Порядок виконання роботи

5.4 Контрольні запитання та завдання

Завдання

Необходимо создать класс «двумерный массив». Соответствующие задания должны быть реализованы в виде методов класса. Интерфейс класса и его реализация должны быть в отдельных модулях: файлах *.h и *.cpp. Кроме того каждый разрабатываемый основной класс должен реализовывать:

1. конструктор по умолчанию

2. деструктор

3. конструкторы с параметрами

4. конструктор копирования

5. перегруженную операцию присваивания

6. перегруженную операцию вывода в поток

7. метод загрузки данных из файла

8. метод сохранение данных в файл

9. заполнение данных случайным образом

5.6 Варіанти завдань

Вариант 1

Дана целочисленная прямоугольная матрица. Определить:

1) количество строк, не содержащих ни одного нулевого элемента;

2) максимальное из чисел, встречающихся в заданной матрице более одного раза.

Вариант 2

Дана целочисленная прямоугольная матрица. Определить количество столбцов, не содержащих ни одного нулевого элемента.

Характеристикой строки целочисленной матрицы назовем сумму ее положительных четных элементов. Переставляя строки заданной матрицы, расположить их в соответствии с ростом характеристик.

Вариант 3

Дана целочисленная прямоугольная матрица. Определить:

1) количество столбцов, содержащих хотя бы один нулевой элемент;

2) номер строки, в которой находится самая длинная серия одинаковых элементов.

Вариант 4

Дана целочисленная квадратная матрица. Определить:

1) произведение элементов в тех строках, которые не содержат отрицательных элементов;

2) максимум среди сумм элементов диагоналей, параллельных главной диагонали матрицы.

Вариант 5

Дана целочисленная квадратная матрица. Определить:

1) сумму элементов в тех столбцах, которые не содержат отрицательных элементов;

2) минимум среди сумм модулей элементов диагоналей, параллельных побочной диагонали матрицы.

Вариант 6

Дана целочисленная прямоугольная матрица. Определить:

1) сумму элементов в тех строках, которые содержат хотя бы один отрицательный элемент;

2) номера строк и столбцов всех седловых точек матрицы.

Вариант 7

Для заданной матрицы размером 8 на 8 найти такие k, что k-я строка матрицы совпадает с k-м столбцом.

Найти сумму элементов в тех строках, которые содержат хотя бы один отрицательный элемент.

Вариант 8

Характеристикой столбца целочисленной матрицы назовем сумму модулей его отрицательных нечетных элементов. Переставляя столбцы заданной матрицы, расположить их в соответствии с ростом характеристик.

Найти сумму элементов в тех столбцах, которые содержат хотя бы один отрицательный элемент.

Вариант 9

Соседями элемента Перегрузка унарных операций. #include <iostream> - student2.ru - в матрице назовем элементы Перегрузка унарных операций. #include <iostream> - student2.ru с i-1 Перегрузка унарных операций. #include <iostream> - student2.ru к Перегрузка унарных операций. #include <iostream> - student2.ru i+1, j-1 Перегрузка унарных операций. #include <iostream> - student2.ru Перегрузка унарных операций. #include <iostream> - student2.ru Перегрузка унарных операций. #include <iostream> - student2.ru j+1, (к, Перегрузка унарных операций. #include <iostream> - student2.ru ) Перегрузка унарных операций. #include <iostream> - student2.ru (i, j). Операция сглаживания матрицы дает новую матрицу того же размера, каждый элемент которой получается как среднее арифметическое имеющихся соседей соответствующего элемента исходной матрицы. Построить результат сглаживания заданной вещественной матрицы размером 10 на 10. В сглаженной матрице найти сумму модулей элементов, расположенных ниже главной диагонали.

Вариант 10

Элемент матрицы называется локальным минимумом, если он строго меньше всех имеющихся у него соседей. Подсчитать количество локальных минимумов заданной матрицы размером 10 на 10.

Найти сумму модулей элементов, расположенных выше главной диагонали.

Вариант 11

Коэффициенты системы линейных уравнений заданы в виде прямоугольной матрицы. С помощью допустимых преобразований привести систему к треугольному виду.

Найти количество строк, среднее арифметическое элементов которых меньше заданной величины.

Вариант 12

Уплотнить заданную матрицу, удаляя из нее строки и столбцы, заполненные нулями. Найти номер первой из строк, содержащих хотя бы один положительный элемент.

Вариант 13

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

Вариант 14

Осуществить циклический сдвиг элементов квадратной матрицы размерности MxN вправо на k элементов таким образом: элементы 1-й строки сдвигаются в последний столбец сверху вниз, из него — в последнюю строку справа налево, из нее — в первый столбец снизу вверх, из него — в первую строку; для остальных элементов — аналогично.

Вариант 15

Дана целочисленная прямоугольная матрица. Определить номер первого из столбцов, содержащих хотя бы один нулевой элемент.

Характеристикой строки целочисленной матрицы назовем сумму ее отрицательных четных элементов. Переставляя строки заданной матрицы, расположить их в соответствии с убыванием характеристик.

Вариант 16

Упорядочить строки целочисленной прямоугольной матрицы по возрастанию количества одинаковых элементов в каждой строке.

Найти номер первого из столбцов, не содержащих ни одного отрицательного элемента.

Вариант 17

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

Найти номер первой из строк, не содержащих ни одного положительного элемента.

Вариант 18

Дана целочисленная прямоугольная матрица. Определить:

1) количество строк, содержащих хотя бы один нулевой элемент;

2) номер столбца, в которой находится самая длинная серия одинаковых элементов.

Вариант 19

Дана целочисленная квадратная матрица. Определить:

1) сумму элементов в тех строках, которые не содержат отрицательных элементов;

2) минимум среди сумм элементов диагоналей, параллельных главной диагонали матрицы.

Вариант 20

Дана целочисленная прямоугольная матрица. Определить:

1) количество отрицательных элементов в тех строках, которые содержат хотя бы один нулевой элемент;

2) номера строк и столбцов всех седловых точек матрицы.

Контрольний приклад

Файл «Tmatr.cpp»

/*

Написать класс "Двумерная матрица"

Необходимо создать класс «двумерный массив».

Интерфейс класса и его реализация должны быть в отдельных модулях: файлах *.h и *.cpp.

Кроме того каждый разрабатываемый основной класс должен реализовывать:

1. конструктор по умолчанию

2. деструктор

3. конструкторы с параметрами

4. конструктор копирования

5. перегруженную операцию присваивания

6. перегруженную операцию вывода в поток

7. метод загрузки данных из файла (в файле первые две цифры указывают на размерность матрицы)

8. метод сохранение данных в файл

Реализовать следующие методы:

1.заполнение данных случайным образом;

2.сортировку указанной строки матрицы.

*/

#include "stdafx.h"

#include "TmatrH.h"

int main()

{

Nmatr::Tmatr matr1, matr2(10,5);

matr1.Rand(5);

matr2.Rand(10);

std::cout<<"Ischodnie dannie:"<<std::endl;

std::cout<<"matr1 = \n"<<matr1<<std::endl;

std::cout<<"matr2 = \n"<<matr2<<std::endl;

std::cout<<"Sum1 = \n"<<matr1.Sum()<<std::endl;

std::cout<<"Sum2 = \n"<<matr2.Sum()<<std::endl;

//Продемонтрируем использование операции "<"

if(matr1<matr2) std::cout<<"matr1<matr2"<<std::endl;

else std::cout<<"matr1>=matr2"<<std::endl;

Nmatr::Tmatr matr3(matr2);

if(!(matr3<matr2)||(matr2<matr3)) std::cout<<"matr3==matr2"<<std::endl;

matr1=matr2;

std::cout<<"matr1 = \n"<<matr1<<std::endl;

Nmatr::Tmatr matr4;

matr4.LoadFromFile("TextMatr.txt");

std::cout<<"matr4 = \n"<<matr4<<std::endl;

matr4.SaveFromFile("TextMatrOut.txt");

//Сортировка указанной строки

matr4.SortStr(2);

std::cout<<"matr4 = \n"<<matr4<<std::endl;

return 0;

}

Файл «TmatrH.h»

#ifndef TmatrH

#define TmatrH

#include <iostream>

#include <fstream>

#include <time.h>

namespace Nmatr{

class Tmatr

{

int **matr;

int n,m;

public:

Tmatr();//конструктор по умолчанию

Tmatr(int,int);//конструктор с параметром

Tmatr(Tmatr &);//конструктор коппирования

~Tmatr();//деструктор

void Rand(int);//метод заполнения случайным образом от 0 до заданного параметра

int Sum();//метод суммирования элементов

bool operator<(Tmatr&);//перегрузка операции "<"

Tmatr& operator=(Tmatr&);//перегрузка операции "="

//перегрузка потоков

friend std::istream& operator>>(std::istream&,Tmatr&);

friend std::ostream& operator<<(std::ostream&,Tmatr&);

void LoadFromFile(char*);//Чтение из файла

void SaveFromFile(char*);//Запись в файла

void SortStr(int);//Сортировка указанной строки

};

//объявление в пространстве имен функций

std::istream& operator>>(std::istream&,Tmatr&);

std::ostream& operator<<(std::ostream&,Tmatr&);

}//end namespace Nmatr

#endif

Файл «Tmatr.cpp»

#include "stdafx.h"

#include "TmatrH.h"

Nmatr::Tmatr::Tmatr()

{ this->n=5;

this->m=5;

matr=new int*[n];

for(int i(0);i<n;i++)

matr[i]=new int[m];

}

Nmatr::Tmatr::Tmatr(int n, int m)

{

this->n=n;

this->m=m;

matr=new int*[n];

for(int i(0);i<n;i++)

matr[i]=new int[m];

}

Nmatr::Tmatr::Tmatr(Tmatr &obj)

{

this->n=obj.n;

this->m=obj.m;

matr=new int*[n];

for(int i(0);i<n;i++)

matr[i]=new int[m];

for(int i(0);i<n;i++)

for(int j(0);j<m;j++)

matr[i][j]=obj.matr[i][j];

};

Nmatr::Tmatr::~Tmatr()

{

for(int i(0);i<n;i++)

delete[]matr[i];

delete[]matr;

}

void Nmatr::Tmatr::Rand(int k)

{

srand(time(NULL));

for(int i(0);i<n;i++)

for(int j(0);j<m;j++)

matr[i][j]=rand()%k;

}

int Nmatr::Tmatr::Sum()

{

int S(0);

for(int i(0);i<n;i++)

for(int j(0);j<m;j++)

S+=matr[i][j];

return S;

}

bool Nmatr::Tmatr::operator<(Nmatr::Tmatr& obj)

{

int S1=this->Sum();

int S2=obj.Sum();

return (S1<S2);

}

Nmatr::Tmatr& Nmatr::Tmatr::operator=(Nmatr::Tmatr& obj)

{

if(this==&obj) return *this;

this->~Tmatr();

this->n=obj.n;

this->m=obj.m;

matr=new int*[n];

for(int i(0);i<n;i++)

matr[i]=new int[m];

for(int i(0);i<n;i++)

for(int j(0);j<m;j++)

matr[i][j]=obj.matr[i][j];

return *this;

}

std::istream& Nmatr::operator>>(std::istream& in,Nmatr::Tmatr& obj)

{

for(int i(0);i<obj.m;i++)

for(int j(0);j<obj.m;j++)

in>>obj.matr[i][j];

return in;

}

std::ostream& Nmatr::operator<<(std::ostream& out,Nmatr::Tmatr& obj)

{

for(int i(0);i<obj.n;out<<'\n',i++)

for(int j(0);j<obj.m;j++)

{

out.width(5);

out<<obj.matr[i][j];

}

out<<'\n';

return out;

}

void Nmatr::Tmatr::LoadFromFile(char* FilaName)//Чтение из файла

{

this->~Tmatr();

matr=new int*[n];

for(int i(0);i<n;i++)

matr[i]=new int[m];

std::ifstream in(FilaName);

in>>this->n;

in>>this->m;

for(int i(0);i<n;i++)

for(int j(0);j<m;j++)

in>>matr[i][j];

}

void Nmatr::Tmatr::SaveFromFile(char* FilaName)//Запись в файла

{ std::ofstream out(FilaName);

out<<this->n<<' ';

out<<this->m<<'\n';

for(int i(0);i<n;out<<'\n',i++)

for(int j(0);j<m;j++)

{

out.width(5);

out<<matr[i][j];

}

out<<'\n';

}

void Nmatr::Tmatr::SortStr(int k)//Сортировка указанной строки

{

if((k<0)||(k>=n))return;

for(int i(0);i<m;i++)

for(int j(0);j<m-1-i;j++)

if(matr[k][j]>matr[k][j+1])

{

int tmp=matr[k][j];

matr[k][j]=matr[k][j+1];

matr[k][j+1]=tmp;

}

}

6 Наслідування, поліморфізм, інкапсуляция

Мета роботи

6.2 Вказівки щодо організації самостійної роботи студентів

Наследование

Производный класс (наследник) может получать атрибуты и поведение уже существующего базового класса. Наследование позволяет “вынести за скобки” то общее, что присуще нескольким классам — общие свойства придаются базовому классу, а отличия — его наследникам.

Примербазового и производного классов: date и birthday.

ß

class date { int day, month, year; public: date(int,int,int); date(char*); };
class birthday: public date { public: string name; };

Конструкторы не наследуются. Если конструктор базового класса имеет параметры, он вызывается в списке инициализации производного конструктора. Конструктор без параметров вызывается автоматически.

Деструктор класса-наследника всегда вызывает деструктор базового класса.

Уровни доступа

Любой элемент класса имеет один из трех уровней доступа:

· private (закрытый) – доступен только из функций-членов данного класса и дружественных функций;

· protected (защищенный) – доступен как private, а также из функций-членов производных классов;

· public (открытый) – доступен всюду, где виден класс.

В объявлении класса обычно сначала перечисляются все открытые элементы, потом защищенные, потом закрытые.

В заголовке производного класса указываются имена всех базовых классов вместе со спецификаторами доступа.

class Derived: сп_доступа Base1 [, сп_доступа Base2,...] {...};

Замечание.Базовых классов больше одного, если наследование множественное.

Спецификаторы определяют уровень доступа к элементам базового класса внутри производного. Уровень доступа к элементу определяется как меньший из двух - того, что элемент имеет внутри базового класса и того, что указан в производном классе (private < protected < public).

Явное указание спецификатора доступа при наследовании не обязательно. По умолчанию принимается private для базовых классов и public для базовых структур и объединений.

Если базовый класс наследуется как private, его публичные элементы будут иметь уровень private в производном классе. Однако можно выборочно вернуть статус публичных некоторым элементам базового класса, переобъявив их в секции public производного класса.

Пример.Возврат утраченного статуса.

ß

class Base { public: void f1(); };
class Derived: private Base { public: Base::f1; // делает f1() снова публичным };

Если элемент описан в базовом классе как private, его никак нельзя сделать public в производном классе.

Виртуальные функции

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

Пример.Класс с виртуальными функциями.

Определим базовый класс date

ß


class date { protected: int day, month, year; public: date(int,int,int); void set_year(int y); void print(); };   date::date(int d, int m, int y) { day = d; month = m; year = y; }   void date::set_year(int y) { year = y; print(); }   void date::print() { printf("%d-%d-%d\n", day, month, year); }

и производный от него класс birthday:

ß

class birthday: public date { public: char name[80]; birthday(int d, int m, int y, char* n); void print(); };   birthday::birthday(int d, int m, int y, char* n) : date(d, m, y) { strcpy(name, n); }   void birthday::print() { printf("%d-%d-%d, dear %s\n", day, month, year, name); }

Следующий код

ß

date* d = new date(19, 10, 1951); birthday* b = new birthday(19, 10, 1951, "Bond"); d->set_year(2001); b->set_year(2001);

напечатает: "19-10-1951" два раза.

Если же сделать метод date::print() виртуальным,

ß

virtual void print(int y);

то тот же код напечатает:

"19-10-1951"

"19-10-1951, dear Bond".

Чтобы сделать метод виртуальным, достаточно объявить его с описателем virtual.

Для виртуальных функций действуют следующие правила:

1) виртуальную функцию нельзя объявлять как static; .

2) спецификатор virtual писать не обязательно при переопределении функции в производном классе, переопределенная функция все равно будет виртуальной.

3) виртуальная функция должна быть определена в классе, где она впервые объявлена или должна быть чисто виртуальной, т.е. не иметь кода.

virtual void print() = 0;

Класс, содержащий чисто виртуальные функции, является абстрактным, объекты такого класса не могут быть созданы. Единственным назначением абстрактных классов является “вынесение за скобки” общих свойств их потомков и обеспечение полиморфизма.

Наши рекомендации