- •Лабораторные работы 1-3 по ооп
- •Справки и пояснения по учебным файлам
- •1. Простейшие опыты
- •2. Исследование дружественных функций. Работа с комплексными числами
- •Лабораторная работа № 2. Перегрузка функций и перегрузка операций
- •2. Комплект файлов point.H, point.Cpp, pointmai.Cpp - класс точка на экране
- •Справки и пояснения по учебным файлам
- •Упражнение 1. Перегрузка функций
- •Упражнения 2. Перегрузка операций
- •1. Данные класса и статус их доступа
- •2. Методы класса Point
1. Данные класса и статус их доступа
Каждая точка на плоскости имеет две координаты x и y. Не стоит упускать возможности использования цвета, чтобы создаваемые объекты могли иметь дополнительные отличия, что обеспечит и большую привлекательность программ создаваемых с использованием нашего класса Point.
В соответствии с общим принципом ООП желательно обеспечивать защищенность координат и цвета от внешнего доступа из других частей программы. С другой стороны, создаваемый нами класс, возможно, будет использоваться как базовый для производных классов различных плоских геометрических фигур. Координаты базовой точки, возможно, будет целесообразно использовать как точку привязки фигуры к плоскости, поэтому разрешим будущим классам-потомкам доступ к параметрам точки привязки и примем статус доступа всех параметров точки как protected.
2. Методы класса Point
Над точками на плоскости можно осуществлять множество различных действий: можно менять координаты и цвет, перемещать, отображать, стирать (прятать), складывать. При этом движения или перемещения точек могут быть разными:
- в нужном направлении на заданное приращение,
- в заданную точку,
- поворот вокруг другой заданной точки P.
Для перемещения на заданное приращение dp=(dx,dy) можно создать два перегруженных метода Move(point& dP) и Move(dx, dy), которые к собственным координатам объекта добавляют соответствующие приращения dp или dx и dy. В теле этих методов должны производиться следующие действия: 1. Спрятать (Hide( )) 2. сменить координаты (x+=dP.x; y+=dP.y) и 4. Отобразить в новом положении (Show( )).
Перемещения в заданную (указанную) точку - MoveTo(point& P) и MoveTo(int xn, int yn) отличаются от предыдущих просто сменой собственных координат объекта x=P.x; y=P.y .
Для поворота данной (текущей) точки вокруг другой заданной точки P на угол φ, назовем метод Rot (от слова Rotation) необходимо рассчитать новые координаты точки (xн, yн). Для этого воспользуемся готовыми формулами, полученными путем мудреных манипуляций (т.н. аффинных преобразований) с системами координат
xн = x cos(φ) – y sin(φ) – P.x cos(φ) + P.y sin(φ) + P.x
yн = x sin(φ) + y cos(φ) – P.x sin(φ) - P.y cos(φ) + P.y (1)
Реализация ‘ этой функции на языке выглядит следующим образом.
point point::Rot(point& P, double dfi){dfi=dfi*M_PI/180; //fi в радианах
double cs=cos(dfi), sn=sin(dfi),xt,yt,a=P.GetX(), b=P.GetY();
xt= x*cs-y*sn -a*cs+b*sn+a;
yt=x*sn+y*cs -a*sn-b*cs+b;
MoveTo(xt,yt); return *this;
}//-----------------------------------------------------------
Заметим, что поскольку текущая, обрабатываемая точка (например, D.Rot(P,dfi)) должна изменить свои координаты метод должен возвращать разъименованный указатель return *this на эту самую точку.
Для доступа к членам других объектов класса point могут потребоваться следующие публичные методы (поскольку данные нашего класса x,y,c защищенные (не public) то компилятор запрещает доступ к членам x,y,c других объектов)
int& GetX(void){return x;}
int& GetY(void){return y;}
void SetXY(int xi,int yi){ x=xi;y=yi;}
void SetC(int ci){ c=ci;}
с подходящими именами “Получить/Установить” Get/Set.
Для упрощения арифметических действий с точками перегрузим операции прибавить/отнять “+” “-”, и “дать приращение dP” - “-=”.
Для экзотики и возможного применения для будущих производных классов перегрузим постфиксную операцию инкремент для циклической смены цвета, например P++. Объект P, при этом будет переливаться всеми цветами радуги.
Для отображения и стирания наших объектов необходимы методы с соответсвующими подходящими именами Show( ) и Hide( ). Метод Show( ) заключается в рисовании объекта его цветом с (для этого вначале установим цвета переднего плана = с), а метод Hide( ) – в рисовании объекта цветом фона.
Таким образом, спроектированный нами класс point на языке С++ имеет следующий набор компонентов:
class point{
protected: // на будущее для классов наследников
int x,y,c;
public:
point(int xi, int yi,int ci); //конструктор-инициализатор
point(const point& P); //конструктор-копии
int& GetX(void){return x;}
int& GetY(void){return y;}
void SetXY(int xi,int yi){ x=xi;y=yi;}
void SetC(int ci){ c=ci;}
point operator+ (point& P);
point operator- (point& P);
point& operator++(int k );
point& operator+=(point& dP); //"движок в направлении dP"
void Move(point& dP); // на приращение dp=(dx,dy)
void Move(int dx, int dy); //-----'--'--
void MoveTo(point& P); // в указанную точку
void MoveTo(int xn, int yn);
point Rot(point& P, double dfi);
void Show(void);
void Print(void); // private:
void Hide();
};//======================================================
Реализация спроектированного нами класса point и иллюстрация его работы см файлы point.h pointm.cpp
#include <iostream.h> #include <graphics.h> #include <conio.h>
#include <dos.h> #include "point.h"
//у класса point есть движок +=dP вариатор цвета F++ MoveTo(point p) и Move(point& dP) //на dP
void main(void){
int i,fi,gd=DETECT,gm; initgraph(&gd,&gm,"");
{
point A(100,100,BLUE), B(200,200,GREEN), C(300,300,GREEN),
E(100,200), T5(200,200,MAGENTA),dP1(1,1),TA;
for(i=0;i<10;i++);
cout<<" появились "; A.Show(); B.Show(); C.Show(); getch();
cout<<"A.Rot(B); - поворот т А вокруг B на 30 гр"<<endl;
getch(); A.Rot(B,30);
cout<<"сдвинем A в т E "; getch(); A.MoveTo(E); delay(500);
cout<<"поворот E.Rot(TT,30) - "; getch(); C.Show(); E.Rot(C,30);
getch(); cout<<"вращение т А вокруг т (300,300) на 450\n"; getch();
A.SetXY(100,100); A.SetC(BLUE);
int dfi=3;
for(fi=0;fi<450;fi+=dfi) { A.Rot(B,dfi); //A.Show();
delay(50); }
cout<<"поворот B.Rot(TT,fi) - "; getch(); B.SetC(MAGENTA);
for(fi=0;fi<450;fi+=dfi) {
C+=dP1; C.Show(); // B+=dP1;
B.Rot(C,dfi); delay(100); //радиус увелич
} getch(); //эта амплитуда совсем другая переменная
double y0=300,y,xt=5,dx=3,k=-0.5,Am=100,w=9*M_PI/(4*180);
cout<<"\nE2.MoveTo(TA) по синусоиде;"; getch();
for(i=0;i<200;i++){
y=y0+Am*sin(w*xt); xt+=dx; delay(50); //k*xt+
TA.SetXY(xt,y); A++; A.MoveTo(TA); // A.Show();
}
cout<<"\nпоследний раз"; getch();
}closegraph(); cout<<"\nСпасибо за внимание"; getch();
}//------------------------------------------------------------------
#ifndef POINTH ПРИЛОЖЕНИЕ // файл point.h
#define POINTH 1
#include <math.h> #include <iostream.h> #include <graphics.h>
#include <conio.h> #include <dos.h>
class point{
protected:
int x,y,c;
public:
point(int xi, int yi,int ci); //конструктор-инициализатор
point(const point& P); //конструктор-копии
int& GetX(void){return x;}
int& GetY(void){return y;}
void SetXY(int xi,int yi){ x=xi;y=yi;}
void SetC(int ci){ c=ci;}
point operator+ (point& P);
point operator- (point& P);
point& operator++(int k );
point& operator+=(point& dP); //движок в направлении dP
void Move(point& dP); // на приращение dp=(dx,dy)
void Move(int dx, int dy); //-----'--'--
void MoveTo(point& P); // в указанную точку
void MoveTo(int xn, int yn);
point Rot(point& P, double dfi);
void Show(void);
void Print(void);
// private:
void Hide();
};//======================================================
//Реализация методов класса point
point::point(int xi=0, int yi=0, int ci=15){x=xi; y=yi;c=ci;}
point::point(const point& P){x=P.x; y=P.y;}
void point::Show(void) {int cc=getcolor(); setcolor(c);
setfillstyle(1,c); fillellipse(x, y,2,2);
setcolor(cc); setfillstyle(1,cc);
}//-----------------------------------------------------
void point::Hide(void) {
int c1=c; c=getbkcolor();
Show(); setcolor(c=c1); // c=c1; //восст цвет
}
point point::operator+ (point& P2){
point P; P.x=x+P2.x;
P.y=y+P2.y; P.c=c; return P;
}//-----------------------
point point::operator- (point& P2){
point P; P.x=x-P2.x;
P.y=y-P2.y; P.c=c; return P;
}//-----------------------
point& point::operator++(int k ){ int c1=c%15+1;
c=c1;; return *this;}//вариатор цвета, k - заглушка
point& point::operator+=(point& P){x+=P.x; y+=P.y; return *this;}//+=движок на dP
void point::Move(point& dP) { //передвинуть на dx,dy
Hide(); x+=dP.x; y+=dP.y; Show();
}
void point::Move(int dx, int dy){
Hide(); x+=dx; y+=dy; Show();
}
void point::MoveTo(int xn, int yn) { Hide(); x=xn; y=yn; Show();
}//----------------------------------------------------
void point::MoveTo(point& P) {
Hide(); x=P.x; y=P.y; Show();
}//----------------------------------------------------
/*void point::LineTo(point& P){
int cc=getcolor(); setcolor(WHITE);
line(x,y,P.GetX(),P.GetY()); setcolor(cc);
this->Move(P.x,P.y);
// Hide(); this->x=p.GetX(); this->y=p.GetY(); Show();
}//-----------------------------------------------------*/
void point::Print(void) { cout <<"x= "<< x<<" y="<<y;}
point point::Rot(point& P, double dfi){dfi=dfi*M_PI/180;
//fi в радианах //алгоритм вращения объекта вокруг точки Р
double cs=cos(dfi), sn=sin(dfi),xt,yt,a=P.GetX(),b=P.GetY();
xt= x*cs-y*sn -a*cs+b*sn+a; //готовые формулы
yt=x*sn+y*cs -a*sn-b*cs+b;
MoveTo(xt,yt); return *this;
}//-----------------------------------------------------------
#endif
КЛАСС ЕГИПЕТСКИЕ ЧИСЛА
#include <iostream.h> // #include <string.h>
#ifndef TESTIOS // #define TESTIOS 1
char ES[]="ЦРП|\0";
class Egipt{
public:
char *Alfavit, *Data; // для строк алф и изобр числа
int Alen,Dlen; //длина строки изобр числа
int Val;
public:
Egipt(int n); //это же прототипы чего придир
Egipt(char *Dat );
Egipt(const Egipt& N);
// Egipt operator=(Egipt& N); //компилятор сам такие делает
int GetVal( ) {return Val;} //для доступа к другим
void Value();
void Kod(int n);
~Egipt();
}; //-----------------------------------------------------
Egipt::Egipt(int n):Alen(4){
int nt=n/1000,ns,nd,ne=n%10;
nd=(n%100)/10; ns=(n%1000)/100;
Dlen=nt+ns+nd+ne; Val=n; //длина строки данных
Data= new char[Dlen+1]; Data[0]='\0';
Alfavit =new char[Alen+1];
strcpy(Alfavit,ES);
this->Kod(n); //конвертер для Data
}//-----------------------------------------------------
Egipt::Egipt(char *Dat="\0"):Alen(4){
Dlen=strlen(Dat); Alfavit =new char[Alen+1];
Data=new char[Dlen+1]; strcpy(Alfavit,ES);
strcpy(Data,Dat); strcat(Data,"\0");
this->Value(); // вычисляет зн Val
}//-----------------------------------------------------
Egipt::Egipt(const Egipt& N):Alen(4){ //копия
Dlen=N.Dlen; Val=N.Val;
Data= new char[Dlen+1]; Alfavit =new char[Alen+1];
strcpy(Alfavit,ES); strcpy(Data,N.Data);
}//-----------------------------------------------------
void Egipt::Value(){ //ЦЦРРРПП||||=2324
int i=0,rez=0; char c=Data[0];
while (c!='\0'){ //дешифратор
switch (c){ //кроме как здесь нигде алфавит не исполь
case 'Ц': rez+=1000; break;
case 'Р': rez+=100; break;
case 'П': rez+=10; break;
case '|': rez+=1; break;
default : cout<<" нет такого символа "<<endl;
};
c=Data[++i]; Val=rez; //рез присвоим член-данному Val
}
}//-------------------------------------------------------
void Egipt::Kod(int n){ //ЦЦРРРПП||||=2324 формирует строку Data
int i,nt=n/1000,ns,nd,ne=n%10; //число тыс сот дес и ед
char T[2]="Ц\0",S[2]="Р\0",D[2]="П\0",E[2]="|\0";
nd=(n%100)/10; ns=(n%1000)/100;
for(i=0;i<nt;i++) strcat(Data,T); //'Ц'-1000
for(i=0;i<ns;i++) strcat(Data,S); //'Р'=100
for(i=0;i<nd;i++) strcat(Data,D); //'П'=10;
for(i=0;i<ne;i++) strcat(Data,E); //сформировали Data[Dlen]
strcat(Data,"\0");
}//-------------------------------------------------------
Egipt::~Egipt() {delete [] Data; delete [] Alfavit;}//декструктор
//-----------------------------------------------------
ostream& operator<<(ostream& out, Egipt N){
out<<N.Data<<" "; return out;
}//-----------------------------------------------------
istream& operator>>(istream& in, Egipt& N){
char *c=new char[50]; //не более 50 симв
in>>c; N=Egipt(c); //неплохо иметь фильтр недоп символов
delete []c; return in;
}//-----------------------------------------------------
#endif
//---------------------------------------
#include <iostream.h> //#include <stdio.h> #include <string.h>
#include <conio.h> #include <dos.h> #include "testio2.h"
void main(void){ //ЦЦРРРПП||||=2324
clrscr(); cout<<"Египетские числа"<<endl;
Egipt E1,E4;
Egipt E2("ЦЦРРРПП||||");
Egipt E3(126);
cout<<"Египетские числа"<<endl;
cout<<"\nегип число E2 = "<<E2;
cout<<" по нашему равно "<<E2.GetVal();
cout<<"\nегипетское число E3 "<<E3.GetVal();
cout<<"по египетски равно "<<E3<<endl;
getch();
E1=E2; cout<<"E1=E2 ="<<E1; //копирует хорошо
cout<<"\nВвести егип число типа ЦЦРРРПП||| "<<endl;
cin>>E1;
cout<<"\nВвели E1= "<<E1<<" знач = "<<E1.GetVal()<<endl;
cout<<"\nвв E4 "; cin>>E4; cout<<E4<<endl;
getch();
}//--------------------------------------
Примеры программ для лаб
Приложение 1
#include <iostream.h> // Файл comp1/cpp
class cmplx {
static int n; //счетчик объектов
double re,im;
public:
cmplx(){ n++; // конструктор 1 по умолч
cout <<"\nсоздался объект № "<<n;}
cmplx(double r, double i){ n++; //конструктор-инициализатор
cout <<"\nсоздался объект № "<<n; re=r; im=i;}
cmplx(cmplx& R){n++; re=R.re; im=R.im; //конструктор копии
cout <<"\nсоздался объект-копия № "<<n;}
/* cmplx(double r=0.0, double i=1.0){ n++; //эквивалентен cmplx(){ }
cout <<"\nсоздался объект № "<<n; re=r; im=i;} */
~cmplx(){cout <<"\nразрушился объект № "<<n--;}
void define(double r=0.0, double i=0.0){re=r; im=i;}
void display(void){
cout <<"("<<re <<"," << im<<")\n";
}
}; //----------------------------------------
int cmplx::n=0;
void main(void){
cmplx x1,x2,x3(3,3),x4,x6;
x4=cmplx(7,7); x4.display();
cmplx x5=cmplx(x3); //конструктор копии
x6=cmplx(2,3); cmplx x7=cmplx(x3); //конструктор копии
x4= x3;
cout <<"X3 = "; x3.display(); cout <<"X4 = "; x4.display();
cout <<"X5 = "; x5.display(); //
cout <<"\nСколько же на самом деле создается объектов ?";
}//====================================================
Приложение 2
#include <iostream.h>
struct complex {
complex (double re=1.0, double im=0)
{ Re=re; Im=im;
cout<<"создался новый объект "<<Re<<" "<<Im<<endl;
} // konstruktor
void display(void){
cout << "("<< Re<<","<<Im<<")"<<endl;}
double &RE(void) {return Re;}
double &IM(void) {return Im;}
friend complex add(complex a1, complex a2);
private:
double Re,Im;
}; //-------------------------------------
complex add(complex a1, complex a2)
{ complex z(a1.Re+a2.Re, a1.Im+a2.Im);
return z;
}
void main(void){
clrscr();
complex CC,SS(10.3,0.22),EE(2.5); complex xx;m
double a,b,c;
CC.display(); SS.display(); EE.display();
complex X=complex(2,3); cout << "X= "; X.display();
a=CC.IM(); b=SS.RE(); c=X.IM();
cout <<"a="<<a<<" b="<<b<<" c="<<c<<endl;;
complex x1(1.0,1.0), x2(5.,5.),x3;
cout <<"\nпри x1 и x2 = "; x1.display(); x2.display();
x3=add(x1,x2);
cout << "имеем x3= "<<endl; x3.display();
}
Приложение 3
#include <iostream.h>
#include <stdio.h>
class cmplx {
public:
float re,im;
public:
void define (float r=0.0, float i=0.0){
re=r; im=i;}
void display(void){
cout <<"("<<re <<"," << im<<")\n";
}
};
void main(void){
cmplx x1,x2,x3, *adrr;
cout <<"обект X1 но не инизиализирован= "; x1.display();
x1.define(); x2.define(2.5,103);
cout <<"комплексная переменная X1 = "; x1.display();
cout <<"\n X2 = "; x2.display();
cout << "при ключе struct компонента im доступна = "<< x2.im;
cout <<"\n X2 = "; x2.display();
Приложение 4
#include "stroka.cpp" // konkat.cpp перегрузка операции + для склейки строк
stroka& operator +(stroka& A, stroka& B);
void main(void){
stroka X("Qui"); stroka Y(" Vivra"); stroka Z(" Verra!");
stroka C,F; C=X+Y+Zпоживем - увидим";
char d[]="склеиват!"; stroka D(d); stroka E(e);
F=D+E+" ***"; F.display(); C.display();
}
stroka& operator +(stroka& a, stroka& b){
int ls=a.len_str()+b.len_str();
stroka *ps; //вспомогат указатель
ps= new stroka(ls); // резервируем память
strcpy(ps->string(),a.string()); strcat(ps->string(),b.string());
ps->len_str()=ls; // сохраняем длину строки
return *ps; // возвращаем новый объект типа строка
}//-----------------------------------------------------------------------------
#include <iostream.h> // stroka.cpp
#include <string.h>
struct stroka{
char *ch;
int len;
public:
stroka(int N=80): len(0)// konstruktor 1
{ch=new char[N+1];ch[0]='\0';}
stroka(const char *s){
len=strlen(s); ch=new char[len+1];
strcpy(ch,s);
}
int &len_str(void) {return len;}
char *string(void) {return ch;}
void display(void){ cout <<"\nдлина строки:"
<<len <<" ее содержимое - "<<ch;}
~stroka() {delete [] ch;}
};
#ifndef POINTH // POINT.H класс point
#define POINTH 1
class point{
protected:
int x,y,c;
public:
point(int xi, int yi, int c);
int &givex(void);
int &givey(void);
void show(void);
void display(void);
void move(int xn=0, int yn=0, int cn=1); //
private:
void hide();
};
#endif
// -------------------------------------------
#ifndef POINTCPP // Файл POINT.CPP
#define POINTCPP 1
#include <graphics.h>
// #include <iostream.h>
#include "point.h"
point::point(int xi=0, int yi=0, int ci=0)
{x=xi; y=yi; c=ci;}
int &point::givex(void) {return x;}
int &point::givey(void) {return y;}
void point::show(void)
{putpixel(x,y,c);}
void point::hide(void)
{putpixel(x,y,getbkcolor());}
void point::move(int xn, int yn, int cn){
hide(); x=xn; y=yn; c=cn; show();
}
#endif
// POINTMAIN ----------------------------
#include <graphics.h>
#include <conio.h>
#include <iostream.h>
#include "point.h"
void point::display(void){
cout << "\t\t\tпараметры объекта x:y:c ="
<< x<<" "<<y<<" "<<c<<endl;}
void main(void){
int i,cv,xt,yt;
point A(200,50,3); point D(500,200,8); point B();
// создали объекты A B и D
int gd=DETECT, gm;
initgraph(&gd,&gm,"c:\borlanndc\bgi");
A.show(); // cout << "Объект A ="<< A.x<<" "<< A.y<<" "<< A.c;
A.display(); getch(); //B.show(); getch();
D.show(); getch(); A.move();
//cout << "объект A ="<< A.x<<" "<< A.y<<" "<< A.c<<endl;
A.display(); getch(); A.move(50,60,9);
// cout << " объект A ="<< A.x<<" "<< A.y<<" "<< A.c<<endl;
A.display(); getch();
for(i=1;i<16;i++){
A.move(50+2*i,60+5*i,i);
cout << " объект A ="<< A.x<<" "<< A.y<<" "<< A.c<<endl;
A.display(); getch(); }
closegraph();
}//==================================================================
Приложение 5
#include <iostream.h> //файл OVRLOAD1.cpp перегрузка + f(arg1,arg2)
#include <string.h>
#include "ovrload1.h"
void main(void){
stroka LAT("VENI VEDI VICI ");
stroka RUS("Пришел Увидел Победил !");
stroka X("VENI "),Y("VEDI "),Z("VICI "),C,F, STR(23);;
LAT.display();
cout <<"\nобъект RUS сoдержит: "<<RUS.string();
STR=LAT; cout <<"\nSTR копия LAT "; STR.display();
cout<<"обращение к компонентам ch len = "
<< LAT.ch<<" len(LAT) ="<<LAT.len;
C="Склейка X +Y + Z "+X+Y+Z; C.display();
char d[]="Ура ",e[]=" склеивает !";
stroka D(d); stroka E(e); F=D+E + " ***"; F.display();
// F=d+e + "----"; F.display(); // симв массив не может, не тот тип
cout<<"вызов как обычной функции F(arg1,arg2) "<<endl;
F=operator+(D,E+ " как F(arg1,arg2) ");
F.display(); cout<<endl;
} //---------------------------------------------
// файл OVRLOAD1.H перегрузка + для строк как f(arg1,arg2)
#include <iostream.h>
#include <string.h>
class stroka{
public:
char *ch;
int len;
stroka(int ); // konstruktor 1
stroka(const char *s); // konstruktor 2
int &len_str(void) {return len;}
char *string(void) {return ch;}
void display(void);
friend stroka& operator +(stroka& a, stroka& b);
~stroka() {delete [] ch;}
}; //-----------------------------------------------------
stroka::stroka(int N=80):len(0){ch=new char[N+1];ch[0]='\0';}
stroka::stroka(const char *s){
len=strlen(s); ch=new char[len+1];
strcpy(ch,s); }
void stroka::display(void){
cout <<"\nдлина строки:"<<len
<<" ее содержимое - "<<ch<<endl;
}//-----------------------------------------------------
stroka& operator +(stroka& a, stroka& b){
int ls=a.len_str()+b.len_str();
stroka *ps; //вспомаг указатель
ps= new stroka(ls); // объект в динамической памяти
strcpy(ps->string(),a.string());
strcat(ps->string(),b.string());
ps->len_str()=ls; // сохраним длину новой строки
return *ps; // возвращаем новый объект
} //-----------------------------------------------------
#include <iostream.h> // файл OVRLOAD2.H перегрузка + в классе
#include <string.h> // для строк как arg1 operator +(arg2)
class stroka{
public:
char *ch; int len;
public:
stroka(int ); // konstruktor 1
stroka(const char *s); // konstruktor 2
int &len_str(void) {return len;}
char *string(void) {return ch;}
void display(void);
stroka& operator +(stroka& b);
~stroka() {delete [] ch;}
}; //-----------------------------------------------------
stroka::stroka(int N=80):len(0){ch=new char[N+1];ch[0]='\0';}
stroka::stroka(const char *s){
len=strlen(s); ch=new char[len+1];
strcpy(ch,s); }
void stroka::display(void){
cout <<"\nдлина строки:"<<len
<<" ее содержимое - "<<ch<<endl;
}//-----------------------------------------------------
stroka& stroka::operator +(stroka& b){
int ls=this->len_str()+b.len_str();
stroka *ps; //вспомаг указатель
ps= new stroka(ls); // созд новая стр где освобождать
strcpy(ps->string(),this->string());
strcat(ps->string(),b.string());
ps->len_str()=ls; // сохраним длину новой строки
return *ps; // возвращаем новый объект
}//-----------------------------------------------------
#include <iostream.h>
#include <string.h>
#include "ovrload2.h"
void main(void){
stroka LAT("VENI VEDI VICI ");
stroka RUS("Пришел Увидел Победил !");
stroka X("VENI "),Y("VEDI "),Z("VICI "),C,F, STR(23);
LAT.display();
cout <<"\nобъект RUS сoдержит: "<<RUS.string();
STR=LAT; cout <<"\nSTR копия LAT "; STR.display();
cout<<"обращение к компонентам .ch .len = "
<< LAT.ch<<" len (LAT) ="<<LAT.len;
// C=X+Y+Z; C.display(); //не раб "Склейка X +Y + Z "+
char d[]="Ура ",e[]=" склеивает !";
stroka D(d); stroka E(e);
F=D+E + " ***"; F.display();
//F=d+e + "----"; F.display(); // симв массив не может, не тот тип
cout<<"вызов как arg1.operator +(arg2) "<<endl;
F= D+ " с одним аргум ";
D=F.operator+(E); D.display(); cout<<endl;
} //---------------------------------------------
#include <iostream.h> // stroka.cpp
#include <string.h>
struct stroka{
char *ch; int len;
public:
stroka(int N=80): // konstruktor 1
len(0)
{ch=new char[N+1];ch[0]='\0';}
stroka(const char *s){
len=strlen(s); ch=new char[len+1]; strcpy(ch,s);
}
int &len_str(void) {return len;}
char *string(void) {return ch;}
void display(void){
cout <<"\nдлина строки:"<<len <<" ее содержимое "<<ch;}
~stroka() {delete [] ch;}
}; //--------------------------------
#include <iostream.h> // stroki.cpp
#include "stroka.cpp"
void main(void){
stroka LAT("VENI VEDI VICI ");
stroka RUS("Пришел, увидел победил "); stroka STR(23);
LAT.display();
cout <<"\nобъект RUS содержит: "<<RUS.string();
STR.display();
STR=LAT; cout <<"\nSTR копия LAT"<<endl; STR.display();
cout <<" "<<endl;
cout << LAT.ch<<" len="<<LAT.len;
}//===============================================================