Классы, как совокупность данных
Лекция 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
Классы, как совокупность данных