#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <ctime>
using namespace std;
//==============================ИСКЛЮЧЕНИЯ======================================
class ZeroException {
string exc;
friend ostream& operator<<(ostream& os, const ZeroException& vi) {
os << "исключение " << vi.exc;
}
public:
ZeroException() {
this->exc = "ZeroException";
}
};
class NegativeException {
string exc;
friend ostream& operator<<(ostream& os, const NegativeException& vi) {
os << "исключение " << vi.exc;
}
public:
NegativeException() {
this->exc = "NegativeException";
}
};
class InvalidAdress {
string exc;
friend ostream& operator<<(ostream& os, const InvalidAdress& vi) {
os << "исключение " << vi.exc;
}
public:
InvalidAdress() {
this->exc = "InvalidAdress";
}
};
//==============================================================================
/**
* <b>Класс - Вектор</b>
*========================
*@autor Arkanium77
*/
class Vector {
int *v; // массив координат
int n; //размерность пространствa
public:
Vector(int n = 2) {
if (n <= 0)throw NegativeException();
v = new int[n];
this->n = n;
for (int i = 0; i < this->n; i++) {
v[i] = 0;
}
}
Vector(int *m, int n = 2) {
if (n <= 0)throw NegativeException();
v = new int[n];
for (int i = 0; i < n; i++) {
v[i] = m[i];
}
this->n = n;
}
Vector(int x, int y) {
v = new int[2];
v[0] = x;
v[1] = y;
this->n = 2;
}
Vector(const Vector& vect) {
v = new int[vect.n];
n = vect.n;
for (int i = 0; i < n; i++) {
v[i] = vect.v[i];
}
}
~Vector() {
//cout << "Деструктор. Освобождение памяти, занимаемой объектом" << endl;
delete [] v;
}
//=========================================================ФУНКЦИИ==========
/**
* <b>Заполнить вектор случайными числами
* @return Вектор, заполненный случайными числами
*/
Vector random() {
//srand(time(0));
Vector a = Vector(n);
for (int i = 0; i < n; i++) {
a.v[i] = rand() % 200 - 100;
}
//cout<<a;
return a;
}
/**
* <b>Равенство векторов</b>
* @param b - второй вектор для сравнения
* @return <code>true</code> - если равны. <br> Иначе - <code>false</code>
*/
bool operator==(Vector b) {
if (b.n != this->n)return false;
for (int i = 0; i < n; i++) {
if (this->v[i] != b.v[i])return false;
}
return true;
}
/**
* <b>Неравенство векторов</b>
* @param b - второй вектор для сравнения
* @return <code>true</code> - если НЕ равны. <br> Иначе - <code>false</code>
*/
bool operator!=(Vector b) {
//Vector a=this;
//Проблема была в том, что если писать this вместо *this всё ломалось из-за плохого приведения типов. Решение было неочевидно для меня.
return !(*this == b);
/*
if (b.n != this->n)return true;
for (int i = 0; i < n; i++) {
if (this->v[i] != b.v[i])return true;
}
return false;
*/
}
//=======================================================ОПЕРАТОРЫ==========
/**
* <b>Переопределённый оператор =</b><br>
* @param b Вектор
* @return Ничего не возвращает. Изменяет объект от которого вызвана на копия
*/
Vector& operator=(Vector b) {
if (*this == b)return *this;
if (b.n != this->n) {
delete []this->v;
this->n = b.n;
this->v = new int [this->n];
}
this->copy(b.v);
return *this;
}
/*
void operator=(Vector b) {
//this->v = &(*(Vector(b).v));
//this->n = b.n;
this->n=b.n;
this->copy(b.v);
}*/
/**
* <b>Переопределённый оператор []</b><br>
* Аналог функции getV()
* @param x - позиция
* @return координату с заданой позиции
*/
int operator[](int x) {
return this->getV(x);
}
/**
* <b>Переопределённый оператор (a,b)</b><br>
* Аналог функции setV()
* @param pos - позиция
* @param obj - новая координата
* @return ничего. Просто изменяет координату на выбранной позиции.
*/
void operator()(int pos, int obj) {
this->setV(pos, obj);
}
/**
* <b>Переопределённый оператор -=</b>
* @param b - вычитаемый вектор
* @return Изменяет объект от которого был вызван
*/
void operator-=(Vector b) {
if (this->n < b.n) {
int *ar = this->v;
*this = Vector(b.n);
this->copy(ar);
}
for (int i = 0; i<this->n; i++) {
this->v[i] -= b.v[i];
}
}
friend const Vector operator-(Vector a, Vector b) {
Vector u = Vector(a.v, a.n);
u -= b;
return Vector(u.v, u.n);
}
/**
* <b>Переопределённый оператор +=</b>
* @param b - вектор-второе слогаемое
* @return Изменяет объект от которого был вызван
*/
void operator+=(Vector b) {
if (this->n < b.n) {
int *ar = this->v;
*this = Vector(b.n);
this->copy(ar);
}
for (int i = 0; i<this->n; i++) {
this->v[i] += b.v[i];
}
/*
if (b.n >= this->n) {
for (int i = 0; i<this->n; i++) {
this->v[i] += b.v[i];
}
} else {
for (int i = 0; i < b.n; i++) {
this->v[i] += b.v[i];
}
}*/
}
friend const Vector operator+(Vector a, Vector b) {
Vector u = Vector(a.v, a.n);
u += b;
return Vector(u.v, u.n);
}
/**
* <b>Переопределённый оператор *=</b>
* @param a - Число-множитель
* @return Изменяет объект от которого был вызван
*/
void operator*=(int a) {
for (int i = 0; i<this->n; i++) {
this->v[i] *= a;
}
}
/**
* <b>Переопределённый оператор *</b>
* @param a - Число-множитель
* @return Новый вектор
*/
friend const Vector operator*(const Vector& b, int a) {
//cout<<endl<<"============"<<endl;
//cout<<this->n<<endl;
//int gg=this->n;
//Vector t=Vector(*this->v,gg);//Почему-то он выделяет память только под 2 ячейки массива. Независимо от способа задания.
//cout<<t.n<<endl<<endl;
Vector u = Vector(b.v, b.n);
u *= a;
return Vector(u.v, u.n);
}
/**
* <b>Переопределённый оператор /=</b>
* @param a - Число-делитель
* @throws ZeroException - ошибка деления на 0
* @return Изменяет объект от которого был вызван
*/
void operator/=(int a) {
if (a == 0) {//perror("Деление на ноль");
throw ZeroException();
}
for (int i = 0; i<this->n; i++) {
this->v[i] /= a;
}
}
/**
* <b>Переопределённый оператор /</b>
* @param a - Число-делитель
* @throws ZeroException - ошибка деления на 0
* @return Новый вектор
*/
friend const Vector operator/(Vector b, int a) {
/*Vector u = Vector(b.v,b.n);
u *= a;
return Vector(u.v,u.n);*/
Vector u = Vector(b.v, b.n);
u /= a;
return Vector(u.v, u.n);
}
/**
* <b>Переопределённый оператор вывода</b>
* @param os поток вывода.
* @param vi Вектор
* @return изменённый поток вывода
*/
friend ostream& operator<<(ostream& os, const Vector& vi) {
//os << "v << " << endl;
//string c = "";
for (int i = 0; i < vi.n; i++) {
os << vi.v[i] << " ";
}
// os << "v << -2 " << endl;
return os;
}
protected:
/**
* <b>Получить координату по позиции</b>
* @param pos - позиция.
* @return Координату
*/
int getV(int pos) {
if (pos < 0 || pos >= this->n)throw InvalidAdress();
return v[pos];
}
/**
* <b>Изменить координату</b>
* @param pos - позиция координаты
* @param obj - новая координата
*/
void setV(int pos, int obj) {
if (pos < 0 || pos >= n)throw InvalidAdress();
this->v[pos] = obj;
}
/**
* <b>Перенос массива</b>
* Техническая функция. ВАЖНО: Размер this.v должен совпадать с размером переносимого массива
* @param v переносимый массив
*/
void copy(int *v) {
int *ar = new int [this->n];
for (int i = 0; i<this->n; i++) {
ar[i] = v[i];
}
this->v = ar;
delete []ar;
}
};
//======================================================================
int main() {
setlocale(0, "");
srand(time(0));
cout << "Russian Русский";
Vector v = Vector(4);
Vector v2 = Vector(4);
v2(0, 16);
v2(1, 2);
v2(2, 2);
v2(3, 1);
v(0, 0);
v(1, 3);
v(2, 2);
v(3, 1);
cout << endl << endl << v;
cout << endl << endl << v2;
v2 *= 2;
cout << endl << endl << v2;
v2 = (v2 * 2);
cout << endl << endl << v2;
//========================ИСКЛЮЧЕНИЯ=======================================
try {
v /= 0;
} catch (ZeroException a) {
cout << endl << a << endl;
}
//=========================================================================
cout << endl << "v:" << v << endl;
v += v2;
cout << "v[0]=" << v[0] << endl;
cout << endl << v;
v = v.random();
cout << endl << "!" << endl << v;
int m[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
v = Vector(m, 9); //Интересный случай. Почему-то с запуском нового конструктора длина вектора не меняется.
Vector v3 = Vector(m, 9); //Vector(v);
cout << endl << "v3:" << v << "-> " << v3 << endl << "v3[5]=" << v3[5];
v = v3.random();
cout << endl << "v3:" << v << "-> " << v3 << endl << "v3[5]=" << v3[5];
v = v3.random();
v3 = v3.random();
cout << endl << "v3:" << v << "-> " << v3 << endl << "v3[5]=" << v3[5];
if (v != v3)cout << endl << "Бинго";
v = v3;
if (v == v3)cout << " X2";
return 0;
}