Классы, как совокупность данных

Лекция 8.

Классы.

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

Данные класса – их еще называют полями (сравнить со структурой) – это характеристики объекта.

Функции класса – методы (функции – члены класса ) описывают действия над данными, эти функции-члены предназначены для доступа к данным.

В простейшем случае описание класса выглядит так:

class имя

{private:

//элементы класса секция private Секций м.б. несколько,

. . . . . . . . . . . . . . . . порядок их не важен.

public:

//элементы класса секция public

. . . . . . . . . . . . . .

};

private и public – это спецификаторы доступа, они управляют видимостью элементов класса. После private стоят элементы, видимые внутри класса. Этот вид доступа принят в классах по умолчанию. Доступ к этим элементам возможен только из функций, расположенных внутри класса, т.е. это возможность защиты этих элементов от доступа функций, расположенных вне класса.

В секции public описываются данные и функции, которые доступны вне класса (это интерфейс класса).

Итак, основополагающей идеей ООП является объединение данных и действий (функций), производимых над этими данными, в одном классе. Говорят : данные и методы инкапсулированы.

Рассмотрим простой пример:

class myclass

{ private:

int dan; // поля могут быть любого типа, кроме типа

char c; //этого класса, но м.б. указателями или ссылками

public: //на этот класс. Инициализация полей не допускается

void show(){cout<<dan<<’ ’<<c<<endl;}

int get_dan(){return dan;}

char get_c() {return c;}

};

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

Определение объектов: Объект – это переменная типа класс.

myclass a1,a2;

myclass x[10];

myclass *pw;

myclass *qw=new myclass(65,’A’);

myclass &t=a1;

Вызов метода класса применяется как вызов метода конкретного объекта, определяется синтаксисом для доступа к элементам структуры:

x[3]. show();

a1.show(); ‘ .’ – операция доступа к члену класса через имя объекта, отобразит на экране значения полей этого объекта.

При обращении через указатель операцию ‘->’ можно выбрать:

cout<<qw->get_dan(); cout<<(*qw).get_dan();

Замечание. В некоторых языках ООП вызовы методов называют сообщениями (посылка сообщения объекту a1 с указанием вывести данные на экран).

Можно при описании класса определить функцию, которая будет задавать значения полей класса:

void set_dan (int d) {dan=d;}

void set_c (char ch) {c=ch;}

a1.set_dan (65); a1.set_c (‘A’);

Однако лучше инициализировать объект в момент создания, а не вызовом функций. Специальные функции конструируют значение объекта в момент создания, выполняется эта функция автоматически, называется она конструктор.

Конструктор отличается от других методов класса:

а) имя конструктора совпадает с именем класса;

б)у конструктора нет типа возвращаемого значения (он вызывается автоматически и ему не надо возврашать кому-то результат работы).

Есть 3 вида конструкторов:

1)При создании объекта специальный конструктор инициализирует поля объекта нулями. Такой конструктор называется конструктор по умолчанию

Если в классе конструктор по умолчанию не объявлен, то компилятор создает его сам. Без него нельзя было бы определить переменные типа класс: myclass a1;

Если для класса объявлен другой конструктор с параметрами (конструктор инициализации), то компилятор не создает свой конструктор по умолчанию. Если он нужен, то его надо объявлять самим.

2) Если необходимо инициализировать какие-то поля конкретными значениями, то необходимо объявить конструктор для инициализации . Их может быть несколько.

myclass a (69,’D’);

3)третий способ инициализации объекта – когда используется уже существующий объект, это конструктор копирования Он имеет единственный параметр – ссылку на объект этого же класса:

myclass (myclass & x) - конструктор копирования. Он вызывается:

(1)при описании объекта с инициализацией другим объектом:

myclass a2 (a1); //a1 определен ранее.

myclass a2 =a1; // это инициализация, а не присваивание.

(2) при передаче объекта в функцию по значению.

(3) при возврате объекта из функции.

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

myclass b(a);

либо myclass с=a; //это не присваивание, здесь вызывается конструктор копирования по умолчанию.

Вывод: из предыдущего ясно, что в классе м.б. описано несколько конструкторов, т.е. мы имеем дело с перегрузкой функций конструкторов. Требуется, чтобы транслятор мог определить однозначно в каждом случае, какой конструктор вызвать.

Деструктор – вид метода, который используется для освобождения памяти, занятой объектом, при выходе из области действия объекта. Вид деструктора:

~ имя_класса () {};

// не возвращает значения и не имеет //аргументов

Деструктор вызывается автоматически. Его иногда можно и не описывать. Но деструктор должен быть описан, если в объекте (в классе) есть указатель на память, выделенную динамически.

Замечание. struct является классом, отличие её – все поля у неё по умолчанию являются полями типа public, т.е. они все доступны.

Пример класса: Обыкновенная дробь p/q. Опишем 3-х файловый проект, но не сразу весь, а частями (слоями)

// fraction.h – интерфейсный файл класса

1)#include <iostream>

2)#include <fstream>

3)using namespace std;

4)class frac // дробь p/q

5) { private:

6) int p; //числитель

7) unsigned int q; //знаменатель

8) public:

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

10) frac( int a, unsigned int b); //конструктор инициализации

11) frac (const frac & c); // конструктор копирования

Передаем аргумент в функцию по ссылке и в то же время хотим защитить его от изменения. Для этого указываем параметр с модификатором const.

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

// методы

13) int getp() const;

14) unsigned int getq() const ;

Константный метод объявляется с ключевым словом const после списка параметров, он не может изменять значения полей класса, может вызывать только константные методы, но его можно вызывать для любых объектов.

void setp(int a);

void setq(unsigned int b);

15) void show()const;

16) frac reduce (); //сокращение дроби

_ Здесь пока заканчивается 1-ая часть fraction.h______________

//fractionR.cpp – Файл реализации

# include "fraction.h"

extern ofstream fout;//файл, объявленный в главной программе, //будет здесь использоваться.

//определение метода вне класса

Если внутри класса описано только объявление метода, сам метод должен быть определен вне класса, вид этого определения:

тип_возвр. имя_класса :: имя _функции(аргументы) { тело}

:: – знак операции глобального разрешения (операция доступа к области видимости), устанавливает связь функции и класса, где эта функция определена.

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

9)frac :: frac () : p(0), q(1) {fout<<"frac()={"<<p<<'/'<<q<<"}"<<endl; }

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

10)frac::frac (int a, unsigned int b): p(a), q(b)

{ reduce(); fout<<"frac (int a, unsigned int b)"<<endl;

if (q==0){fout<<" denominator 'q' is zero!"<<endl; exit(5); }}

11) frac::frac(const frac & c) : p(c.p), q(c.q )

{fout<<"frac(const frac&["<<c<<"])={"<<p<<'/'<<q<<"}"<<endl; }

12)frac::~frac() // деструктор

{ fout<<"Destructor ~frac() for {"<<p<<'/'<<q<<"}"<<endl; }

13)int frac::getp()const{return p;}

14)unsigned int frac::getq() const{return q;}

void frac::setp(int a){p=a;}

void frac::setq(unsigned int b)

{ if (b!=0){q=b;}

else {fout<<"Cann't divide by zero: denominator 'q' is zero!"<<endl; exit(5);}}

15)void frac::show() const

{ fout<<"{"<<getp()<<'/'<<getq()<<"}"<<endl;

fout<<"show()"<<endl;}

16)frac frac::reduce ()

{ unsigned int s0;

unsigned int s1=abs(p);

fout<<"Do reduce()..."<<endl;

unsigned int s2=q;

while (s2>0)

{ s0=s1;

s1=s2;

s2=s0%s1;}

p=p/int(s1);

q=q/s1;

fout<<"Reduce()={"<<p<<'/'<<q<<"}"<<endl;

return *this;

}

Указатель this.

Каждый объект содержит свой экземпляр полей класса. Методы класса находятся в памяти в единственном экземпляре и используются всеми объектами совместно. Каждый раз, когда некоторый объект использует метод, необходимо, чтобы этот метод использовал внутри себя поля именно того объекта, который этот метод вызвал. Это обеспечивается передачей в функции-методы скрытого параметра this – это указатель на вызвавший функцию объект, он используется внутри метода для ссылок на элементы объекта. В явном виде этот указатель используется для возвращения из метода указателя (return this;) или ссылки на вызвавший объект (return *this;)

// fractiongl.cpp 3-ий файл Главная программа

#include "fraction.h"

ofstream fout;

int main()

{fout.open("res1.txt”); if(fout.fail()){cout<<"oshibka res1.txt";return 2;}

fout<<” frac ff;”<<endl;

frac ff;

fout<<” frac a(2,4),b(2,3);”<<endl;

frac a(2,4),b(2,3);

fout<<” a.show();”<<endl;

a.show();

fout<<” frac c(4,3),d(2,5);”<<endl;

frac c(4,3),d(2,5);

fout<<” frac x,t;”<<endl;

frac x,t;

fout.close();

return 0;

}

Файл res1.txt (1 часть)

frac ff;

frac()={0/1}

frac a(2,4),b(2,3);

Do reduce()...

Reduce()={1/2}

frac (const frac &[{1/2}])={1/2}

Destructor ~frac() for {1/2}

frac (int a, unsigned int b)

Do reduce()...

Reduce()={2/3}

frac (const frac &[{2/3}])={2/3}

Destructor ~frac() for {2/3}

frac (int a, unsigned int b)

a.show();

{1/2}

show()

frac c(4,3),d(2,5);

Do reduce()...

Reduce()={4/3}

frac (const frac &[{4/3}])={4/3}

Destructor ~frac() for {4/3}

frac (int a, unsigned int b)

Do reduce()...

Reduce()={2/5}

frac (const frac &[{2/5}])={2/5}

Destructor ~frac() for {2/5}

frac (int a, unsigned int b)

frac x,t;

frac()={0/1}

frac()={0/1}

____________________________________-

Файл fraction.h – интерфейсный файл класса (продолжение 1)

//некоторые функции (возможные варианты сложения дробей )

17) void addfrac(frac &a, frac &b);

18) frac& addfrac (frac &a);

Файл fractionR.cpp – файл реализации (продолжение 1)

17) void frac::addfrac(frac &a,frac &b)

{ fout<<"Do addfrac(frac &["<<a<<"],frac &["<<b<<"])..."<<endl;

p=a.p*b.q+a.q*b.p;q=a.q*b.q;

fout<<"Result={"<<p<<'/'<<q<<"}"<<endl;

reduce(); //p, q, reduce() относятся к объекту, для которого

} // вызвана функция

-------------------------------------------------------------------------------------

Раньше было:

frac frac::addfrac(frac &a,frac &b)

{ fout<<"Do addfrac(frac &["<<a<<"],frac &["<<b<<"])..."<<endl;

p=a.p*b.q+a.q*b.p;q=a.q*b.q;

fout<<"Result={"<<p<<'/'<<q<<"}"<<endl;

reduce(); //p, q, reduce() относятся к объекту, для которого

return *this;} // вызвана функция

//x=p3.addfrac(p1,p2);

Do addfrac(frac &[{2/3}],frac &[{4/3}])...

Result={18/9}

Do reduce()...

Reduce()={2/1}

frac (const frac &[{2/1}])={2/1}

Destructor ~frac() for {2/1}

//p3.show();

{2/1}

___________________________________________________

18) frac& frac::addfrac (frac &a) //сумма вычисляется путем

{return frac(p*a.q+a.p*q,q*a.q); } // сложения 2-х дробей: 1- к

// которой применяется метод,

//2-я –параметр функции

Файл fractiongl.cpp (продолжение 1)

Вызов 17) функции x.addfrac(b,c); //2/3 +4/3 =2/1

x.show();

Do addfrac(frac &[{2/3}],frac &[{4/3}])...

Result={18/9}

Do reduce()...

Reduce()={2/1}

Вызов 18) функции :x=b.addfrac(c) ; //2/3 +4/3 =2/1

x.show();

Do reduce()...

Reduce()={2/1}

frac (int a, unsigned int b)

Destructor ~frac() for {2/1}

___________________________________________________

Файл fraction.h – интерфейсный файл класса (продолжение 2)

Гораздо удобнее перегрузка операции для объекта класса, она выглядит так:

тип operator операция (список параметров) {тело функции}

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

frac operator +(frac &); //x=a+b;

bool operator <(frac &);

frac& operator=(frac);//не нужна для данных стат. размещения

frac operator -();

frac operator -(frac &);

frac operator *(frac &);

frac operator / (frac &)

Файл fractionR.cpp – файл реализации

frac frac::operator +(frac &c)

{return frac (p*c.q+q*c.p, q*c.q);}

bool frac::operator <(frac &c)

{return (p*c.q < c.p*q)? true:false;}

frac frac::operator - ()

{return frac (-p, q);}

frac frac::operator - (frac &c)

{return frac (p*c.q-q*c.p, q*c.q);}

frac frac::operator * (frac &c)

{return frac (p*c.p, q*c.q);}

frac frac::operator /(frac &c)

{return frac (p*c.q, q*c.p);}

// fractiongl.cpp – продолжение 2

x=b*c; x.show();

operator *(frac& [{4/3}])

Do reduce()...

Reduce()={8/9}

frac (int a, unsigned int b)

Destructor ~frac() for {8/9}

{8/9}

t=a+x; t.show();

operator +(frac &[{8/9}])

Do reduce()...

Reduce()={25/18}

frac (int a, unsigned int b)

Destructor ~frac() for {25/18}

{25/18}

x=c/d; x.show();

x=b-x; x.show();

x=t*x; x.show();

x=(a+b*c)*(b-c/d);

operator /(frac & [{2/5}])

Do reduce()...

Reduce()={10/3}

frac (int a, unsigned int b)

operator -(frac & [{10/3}])

Do reduce()...

Reduce()={-8/3}

frac (int a, unsigned int b)

operator *(frac& [{4/3}])

Do reduce()...

Reduce()={8/9}

frac (int a, unsigned int b)

operator +(frac &[{8/9}])

Do reduce()...

Reduce()={25/18}

frac (int a, unsigned int b)

operator *(frac& [{-8/3}])

Do reduce()...

Reduce()={-100/27}

frac (int a, unsigned int b)

Destructor ~frac() for {-100/27}

Destructor ~frac() for {25/18}

Destructor ~frac() for {8/9}

Destructor ~frac() for {-8/3}

Destructor ~frac() for {10/3}

x={-100/27}

__________________________________

Файл fraction.h

Дружественные функции:

- не представляют свойств класса, но входят в его интерфейс, и имеют доступ к его полям;

- определяются внутри класса со словом friend;

- на него не распространяются спецификаторы доступа;

- ей не передается this;

- описание алгоритма – вне класса, не повторяется слово friend, нет операции frac:: .

friend ostream & operator <<(ostream &,const frac &);

};

Файл fractionR.cpp – файл реализации

ostream & operator <<(ostream &f,const frac &c)

{ f<<"{"<<c.p<<'/'<<c.q<<"}";

return f;

}

Лекция 9.

//MyDinMasHead.h

#include <iostream>

#include <fstream>

using namespace std;

class VEC

{private:

double *v; // указатель на вектор

int ne; // длина вектора

public:

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

VEC(int); // конструктор инициализации

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

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

double& operator [] (int); ///перегрузка операции индексир.

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

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

};

//MyMasDinReal.cpp //–– файл реализации

#include "MyDinMasHead.h"

extern ofstream fo;

VEC::VEC():ne(0),v(NULL)

{fo<<"VEC() \n"; }

VEC::VEC(int n) : ne(n), v(new double[n])

{fo<<"cst1 "<<this<<' '<<v<<endl;}

VEC :: VEC (VEC& a) //К-р инициализирует чистую память

{int i; ne=a.ne;

v=new double[ne];

for (i=0; i<ne; i++) v[i] = a.v[i];

//*this=a; // это копирование здесь не работает (поверхностное)

//Объект а:

//а. ne; a.v-–>

// this->v=a.v; эта ссылка будет неопред., если а будет удалено.

//this->ne=a.ne; Здесь необходимо копирование глубинное.

fo<<"VEC(VEC& a)-cst2"<<this<<' '<<v<<endl;

}

VEC::~VEC()

{fo<<"~VEC()dst "<<this<<' '<<v<<endl;

delete []v;

}

double& VEC::operator [] (int i)

{if (i<0 ||i>=ne) {fo<<"index is out of diapazon"<<endl;

exit (0);}

return v[i];

}

VEC& VEC::operator = (VEC& y)

{int i; fo<< "VEC::operator=(VEC& y)"<<this<<' '<<v<<endl;

if(y.ne!=ne){ delete [] v;

ne=y.ne; v=new double[ne];

for(i=0; i<ne; i++) v[i]=y.v[i];}

else if(this!=&y) for(i=0; i<ne; i++) v[i]=y.v[i];

return *this;

}

VEC VEC::operator+(VEC& y)

{int i, nm, p;

//fo<<"VEC::operator+(VEC& y)"<<this<<' '<<&y<<endl;

nm=y.ne;p=0; if(ne>nm) {nm=ne;p=1;}

VEC z(nm); //VEC* z = new VEC(nm); чтобы работало с &

if(p){z=*this;

for(i=0;i<y.ne;i++)

z.v[i]=z.v[i]+y.v[i];}

else {z=y;for(i=0;i<ne;i++)z.v[i]=z.v[i]+v[i];}

return z;

}

//MyMasDinGlav.cpp

#include "MyDinMasHead.h"

ofstream fo("output.txt");

void main()

{fo<<"out vectm2"<<endl<<endl;

fo<<"VEC x"<<endl;

VEC x;

int i;

VEC a(5),b(5),c(5),d(5),e(7),f(7);

for(i=0;i<5;i++){a[i]=i;b[i]=i+1;c[i]=2*i;d[i]=0;}

for(i=0;i<7;i++)e[i]=i;

fo<<"a:"<<endl;

for(i=0;i<5;i++)

fo<<a[i]<<' ';

}

fo<<endl;

fo<<"b:"<<endl;

for(i=0;i<5;i++)

{fo<<b[i]<<' ';

}

fo<<endl; a: Лекция 9.

//MyDinMasHead.h

#include <iostream>

#include <fstream>

using namespace std;

class VEC

{private:

double *v; // указатель на вектор

int ne; // длина вектора

public:

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

VEC(int); // конструктор инициализации

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

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

double& operator [] (int); ///перегрузка операции индексир.

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

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

};

//MyMasDinReal.cpp //–– файл реализации

#include "MyDinMasHead.h"

extern ofstream fo;

VEC::VEC():ne(0),v(NULL)

{fo<<"VEC() \n"; }

VEC::VEC(int n) : ne(n), v(new double[n])

{fo<<"cst1 "<<this<<' '<<v<<endl;}

VEC :: VEC (VEC& a) //К-р инициализирует чистую память

{int i; ne=a.ne;

v=new double[ne];

for (i=0; i<ne; i++) v[i] = a.v[i];

//*this=a; // это копирование здесь не работает (поверхностное)

//Объект а:

//а. ne; a.v-–>

// this->v=a.v; эта ссылка будет неопред., если а будет удалено.

//this->ne=a.ne; Здесь необходимо копирование глубокое.

fo<<"VEC(VEC& a)-cst2"<<this<<' '<<v<<endl;

}

VEC::~VEC()

{fo<<"~VEC()dst "<<this<<' '<<v<<endl;

delete []v;

}

double& VEC::operator [] (int i)

{if (i<0 ||i>=ne) {fo<<"index is out of diapazon"<<endl;

exit (0);}

return v[i];

}

VEC& VEC::operator = (VEC& y)

{int i; fo<< "VEC::operator=(VEC& y)"<<this<<' '<<v<<endl;

if(y.ne!=ne){ delete [] v;

ne=y.ne; v=new double[ne];

for(i=0; i<ne; i++) v[i]=y.v[i];}

else if(this!=&y) for(i=0; i<ne; i++) v[i]=y.v[i];

return *this;

}

VEC VEC::operator+(VEC& y)

{int i, nm, p;

//fo<<"VEC::operator+(VEC& y)"<<this<<' '<<&y<<endl;

nm=y.ne;p=0; if(ne>nm) {nm=ne;p=1;}

VEC z(nm); //VEC* z = new VEC(nm); чтобы работало с &

if(p){z=*this;

for(i=0;i<y.ne;i++)

z.v[i]=z.v[i]+y.v[i];}

else {z=y;for(i=0;i<ne;i++)z.v[i]=z.v[i]+v[i];}

return z;

}

//MyMasDinGlav.cpp

#include "MyDinMasHead.h"

ofstream fo("output.txt");

void main()

{fo<<"out vectm2"<<endl<<endl;

fo<<"VEC x"<<endl;

VEC x;

int i;

VEC a(5),b(5),c(5),d(5),e(7),f(7);

for(i=0;i<5;i++){a[i]=i;b[i]=i+1;c[i]=2*i;d[i]=0;}

for(i=0;i<7;i++)e[i]=i;

fo<<"a:"<<endl;

for(i=0;i<5;i++)

fo<<a[i]<<' ';

}

fo<<endl;

fo<<"b:"<<endl;

for(i=0;i<5;i++)

{fo<<b[i]<<' ';

}

fo<<endl; a: Лекция 9.

//MyDinMasHead.h

#include <iostream>

#include <fstream>

using namespace std;

class VEC

{private:

double *v; // указатель на вектор

int ne; // длина вектора

public:

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

VEC(int); // конструктор инициализации

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

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

double& operator [] (int); ///перегрузка операции индексир.

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

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

};

//MyMasDinReal.cpp //–– файл реализации

#include "MyDinMasHead.h"

extern ofstream fo;

VEC::VEC():ne(0),v(NULL)

{fo<<"VEC() \n"; }

VEC::VEC(int n) : ne(n), v(new double[n])

{fo<<"cst1 "<<this<<' '<<v<<endl;}

VEC :: VEC (VEC& a) //К-р инициализирует чистую память

{int i; ne=a.ne;

v=new double[ne];

for (i=0; i<ne; i++) v[i] = a.v[i];

//*this=a; // это копирование здесь не работает (поверхностное)

//Объект а:

//а. ne; a.v-–>

// this->v=a.v; эта ссылка будет неопред., если а будет удалено.

//this->ne=a.ne; Здесь необходимо копирование глубокое.

fo<<"VEC(VEC& a)-cst2"<<this<<' '<<v<<endl;

}

VEC::~VEC()

{fo<<"~VEC()dst "<<this<<' '<<v<<endl;

delete []v;

}

double& VEC::operator [] (int i)

{if (i<0 ||i>=ne) {fo<<"index is out of diapazon"<<endl;

exit (0);}

return v[i];

}

VEC& VEC::operator = (VEC& y)

{int i; fo<< "VEC::operator=(VEC& y)"<<this<<' '<<v<<endl;

if(y.ne!=ne){ delete [] v;

ne=y.ne; v=new double[ne];

for(i=0; i<ne; i++) v[i]=y.v[i];}

else if(this!=&y) for(i=0; i<ne; i++) v[i]=y.v[i];

return *this;

}

VEC VEC::operator+(VEC& y)

{int i, nm, p;

//fo<<"VEC::operator+(VEC& y)"<<this<<' '<<&y<<endl;

nm=y.ne;p=0; if(ne>nm) {nm=ne;p=1;}

VEC z(nm); //VEC* z = new VEC(nm); чтобы работало с &

if(p){z=*this;

for(i=0;i<y.ne;i++)

z.v[i]=z.v[i]+y.v[i];}

else {z=y;for(i=0;i<ne;i++)z.v[i]=z.v[i]+v[i];}

return z;

}

//MyMasDinGlav.cpp

#include "MyDinMasHead.h"

ofstream fo("output1.txt");

void main()

{fo<<"out vectm2"<<endl<<endl;

fo<<"VEC x"<<endl;

VEC x;

int i;

VEC a(5),b(5),c(5),d(5),e(7),f(7);

for(i=0;i<5;i++){a[i]=i;b[i]=i+1;c[i]=2*i;d[i]=0;}

for(i=0;i<7;i++)e[i]=i;

fo<<"a:"<<endl;

for(i=0;i<5;i++)

fo<<a[i]<<' ';

}

fo<<endl;

fo<<"b:"<<endl;

for(i=0;i<5;i++)

{fo<<b[i]<<' ';

}

fo<<endl; // a: 1 2 3 4 5

d=a+b+c+d; // b: 1 2 3 4 5

fo<<"d:"<<endl; // c: 0 2 4 6 8

// d: 2 6 10 14 18

d:

for(i=0;i<5;i++)

{fo<<d[i]<<' ';

}

fo<<endl;

fo<<"c:"<<endl;

for(i=0;i<5;i++)

{fo<<c[i]<<' ';

}

d=d+c;

fo<<"d=d+c:"<<endl;

for(i=0;i<5;i++){ fo<<d[i]<<' ';}

fo<<endl;

VEC r(a);

f= a+e;

for(i=0;i<7;i++){ fo<<f[i]<<' ';}

fo<<endl;

fo<<"x=a"<<endl;

x=a;

fo<<"x:"<<endl;

for(i=0;i<5;i++)

{ fo<<x[i]<<' ';

}

out vectm1

VEC x

VEC()

cst1 0012FF34 00365710

cst1 0012FF24 00366D20

cst1 0012FF14 00366D78

cst1 0012FF04 00366EF8

cst1 0012FEF4 00366F50

cst1 0012FEE4 00366FB8

a:

0 1 2 3 4

VEC::operator=(VEC& y)0012FF50 00000000

x=a=b;

VEC::operator=(VEC& y)0012FF34 00365710

VEC::operator=(VEC& y)0012FF50 00367020

b:

1 2 3 4 5

VEC::operator+(VEC& y)0012FF34 0012FF24

VEC z(nm);0012FF34 0012FF24

cst1 0012FD30 00367078

VEC::operator=(VEC& y)0012FD30 00367078

VEC(VEC& a)-cst20012FDC4 003670D0

VEC::operator+(VEC& y)0012FDC4 0012FF14

VEC z(nm);0012FDC4 0012FF14

cst1 0012FD38 00367078

VEC::operator=(VEC& y)0012FD38 00367078

VEC(VEC& a)-cst20012FDD4 00367128

VEC::operator+(VEC& y)0012FDD4 0012FF04

VEC z(nm);0012FDD4 0012FF04

cst1 0012FD40 00367078

VEC::operator=(VEC& y)0012FD40 00367078

VEC(VEC& a)-cst20012FDE4 00367180

VEC::operator=(VEC& y)0012FF04 00366EF8

d:

2 6 10 14 18

c:

0 2 4 6 8 VEC::operator+(VEC& y)0012FF04 0012FF14

VEC z(nm);0012FF04 0012FF14

cst1 0012FD40 00367078

VEC::operator=(VEC& y)0012FD40 00367078

VEC(VEC& a)-cst20012FDF4 003670D0

VEC::operator=(VEC& y)0012FF04 00366EF8

d=d+c:

2 8 14 20 26

VEC(VEC& a)-cst20012FED4 00367078

VEC::operator+(VEC& y)0012FF34 0012FEF4

VEC z(nm);0012FF34 0012FEF4

cst1 0012FD40 003670D0

VEC::operator=(VEC& y)0012FD40 003670D0

VEC(VEC& a)-cst20012FE04 00367138

VEC::operator=(VEC& y)0012FEE4 00366FB8

1 3 5 7 9 5 6

x=a

VEC::operator=(VEC& y)0012FF50 00367020

x:

1 2 3 4 5

d=a+b+c+b;

fo<<"d:"<<endl;

for(i=0;i<5;i++)

{fo<<d[i]<<' ';

}

fo<<endl;

fo<<"c:"<<endl;

for(i=0;i<5;i++)

{fo<<c[i]<<' ';

}

d=d+c;

fo<<"d=d+c:"<<endl;

for(i=0;i<5;i++){ fo<<d[i]<<' ';}

fo<<endl;

VEC r(a);

f=e; //a+e;

for(i=0;i<7;i++){ fo<<f[i]<<' ';}

fo<<endl;

fo<<"x=a"<<endl;

x=a;

fo<<"x:"<<endl;

for(i=0;i<5;i++)

{ fo<<x[i]<<' ';

}

out vectm2

VEC x

VEC()

cst1 0012FF34 003556A8

cst1 0012FF24 00356CB8

cst1 0012FF14 00356D10

cst1 0012FF04 00356E90

cst1 0012FEF4 00356EE8

cst1 0012FEE4 00356F50

a:

0 1 2 3 4

VEC::operator=(VEC& y)0012FF50 00000000

x=a=b;

VEC::operator=(VEC& y)0012FF34 003556A8

VEC::operator=(VEC& y)0012FF50 00356FB8

b:

1 2 3 4 5

cst1 0012FD30 00357010

VEC::operator=(VEC& y)0012FD30 00357010

VEC(VEC& a)-cst20012FDC4 00357068

cst1 0012FD38 00357010

VEC::operator=(VEC& y)0012FD38 00357010

VEC(VEC& a)-cst20012FDD4 003570C0

cst1 0012FD40 00357010

VEC::operator=(VEC& y)0012FD40 00357010

VEC(VEC& a)-cst20012FDE4 00357118

VEC::operator=(VEC& y)0012FF04 00356E90

d:

2 6 10 14 18

c:

0 2 4 6 8 cst1 0012FD40 00357010

VEC::operator=(VEC& y)0012FD40 00357010

VEC(VEC& a)-cst20012FDF4 00357068

VEC::operator=(VEC& y)0012FF04 00356E90

d=d+c:

2 8 14 20 26

VEC(VEC& a)-cst20012FED4 00357010

cst1 0012FD40 00357068

VEC::operator=(VEC& y)0012FD40 00357068

VEC(VEC& a)-cst20012FE04 003570D0

VEC::operator=(VEC& y)0012FEE4 00356F50

1 3 5 7 9 5 6

x=a

VEC::operator=(VEC& y)0012FF50 00356FB8

x:

1 2 3 4 5

VEC x

VEC()

cst1 0012FF34 003556A8

cst1 0012FF24 00356CB8

cst1 0012FF14 00356D10

cst1 0012FF04 00356E90

cst1 0012FEF4 00356EE8

cst1 0012FEE4 00356F50

a:

0 1 2 3 4

VEC::operator=(VEC& y)0012FF50 00000000

x=a=b;

VEC::operator=(VEC& y)0012FF34 003556A8

VEC::operator=(VEC& y)0012FF50 00356FB8

b:

1 2 3 4 5

cst1 0012FD30 00357010

VEC::operator=(VEC& y)0012FD30 00357010

VEC(VEC& a)-cst20012FDC4 00357068

cst1 0012FD38 00357010

VEC::operator=(VEC& y)0012FD38 00357010

VEC(VEC& a)-cst20012FDD4 003570C0

cst1 0012FD40 00357010

VEC::operator=(VEC& y)0012FD40 00357010

VEC(VEC& a)-cst20012FDE4 00357118

VEC::operator=(VEC& y)0012FF04 00356E90

d:

2 6 10 14 18

c:

0 2 4 6 8 cst1 0012FD40 00357010

VEC::operator=(VEC& y)0012FD40 00357010

VEC(VEC& a)-cst20012FDF4 00357068

VEC::operator=(VEC& y)0012FF04 00356E90

d=d+c:

2 8 14 20 26

VEC(VEC& a)-cst20012FED4 00357010

cst1 0012FD40 00357068

VEC::operator=(VEC& y)0012FD40 00357068

VEC(VEC& a)-cst20012FE04 003570D0

VEC::operator=(VEC& y)0012FEE4 00356F50

1 3 5 7 9 5 6

x=a

VEC::operator=(VEC& y)0012FF50 00356FB8

x:

1 2 3 4 5

PAGE \* MERGEFORMAT 30

Классы, как совокупность данных