Міністерство освіти і науки України
Національний університет “Львівська політехніка”
Інститут прикладної математики та фундаментальних наук
Кафедра прикладної математики
Лабораторна робота №0
з курсу Об’єктно-орієнтоване програмування
Тема : Побудова класів у С++
Мета : Побудувати клас згідно заданої предметної області
Хід роботи :
Згідно умови задачі потрібно побудувати декілька класів : для роботи з інформацією про студента, групу,  у якій знаходяться студенти, порівняння членів класу студент, а також методів сортування.
В процесі створення класу потрібно забезпечити можливість введення-виведення студентів та їх сортування. Критерій будь-який (тобто сортувати по імені, прізвищу, групі, середньому значенню оцінок). Створити можливість вибирати один із двох методів сортування – метод “бульбашки” та метод “човник”.
У модулі тестування ми реалізували наші потреби за допомогою функцій наших класів, а саме у ході виконання програми ми будемо вводити, сортувати та виводити інформацію про певні складові класу Group.
main.cpp
#include <iostream>
#include "Group.h"
void main(void)
{
	Group pm21;
	pm21.input();
	pm21.sort();
	pm21.output();
	
}
Group.h
#ifndef _Group_
#define _Group_
#include "Student.h"
class Group
{
public:
	void input(void);
	void output(void);
	void sort(void);
	friend class Sorter;
	//  SYSTEM
	Group();
	Group(int);
	Group(const Group &);
	~Group();
	Group & operator=(const Group &);
	Student & operator[](int i);
private:
	Student *m_ptrMasStudents;
	int m_kilkStudents;
};
#endif
Group.cpp
#include <iostream>
#include <string.h>
#include "Group.h"
#include "Comparer.h"
#include "Sorter.h"
void Group::input(void)
{
	cout<<"BBEDiTb 6yDb-LACKA 4UCL0 CTyDEHTiB:"<<endl;
	cin>>m_kilkStudents;
	cout<<endl<<"\tBBiD"<<endl;
	m_ptrMasStudents= new Student [m_kilkStudents];
	for(int i=0;i<m_kilkStudents;++i)
	{
		cin.ignore(1,'\n');
		cout<<"iMJA:";
		(*this)[i].setName();
		cout<<endl<<"nPU3BUWE:";
		(*this)[i].setSurname();
		cout<<endl<<"GpynA:";
		(*this)[i].setGroup();
		cout<<endl<<"0ziHKU:"<<endl;;
		(*this)[i].setMarks();
		cout<<endl;
	}
}
void Group::output(void)
{
	for(int i=0;i<m_kilkStudents;++i)
	{
		/*char tempBuffer[20];
		m_ptrMasStudents[i].getName(tempBuffer);
		cout<<tempBuffer<<"\t";
		m_ptrMasStudents[i].getSurname(tempBuffer);
		cout<<tempBuffer<<"\t";
		m_ptrMasStudents[i].getGroup(tempBuffer);
		cout<<tempBuffer<<"\t";
		int aTemp[5];
		m_ptrMasStudents[i].getMarks(aTemp);
		for(int j=0;j<5;++j)
			cout<<aTemp[j]<<"  ";
		cout<<endl;*/
		cout<<(*this)[i];
	}
	
}
void Group::sort(void)
{
	cout<<"\nBBEDiTb Cn0Ci6 C0PTyBAHH9l MACUBy:"<<endl
		<<"1 - 3A iMEHEM \n 2 - 3A nPi3BUWEM \n 3 - 3A GPyn0ju \n 4 - 3A 0ciHKAMU(CEPEDHIj 6AL) \n"
		<<"iHWE 4UCL0 - 3A iMEHEM\n";
	PTR_SORT  ptrSort=0;
	int k;
	cin>>k;
	switch(k)
	{
	/*case 1 : ptrSort=&Student::sortByName; break;
	case 2 : ptrSort=&Student::sortBySurname; break;
	case 3 : ptrSort=&Student::sortByGroup; break;
	case 4 : ptrSort=&Student::sortByMarks; break;
	default: ptrSort=&Student::sortByName; break;*/
	case 1 : ptrSort=&Comparer::sortByName; break;
	case 2 : ptrSort=&Comparer::sortBySurname; break;
	case 3 : ptrSort=&Comparer::sortByGroup; break;
	case 4 : ptrSort=&Comparer::sortByMarks; break;
	default: ptrSort=&Comparer::sortByName; break;
	}
	cout<<"/nBBEDiTb METOD COPTyBAHH9l"<<endl
		<<"1 - 6yLb6AWKA \n 2 - LiHIjHA BU6iPKA \n 3 - 40BHUK \n 4 - WBUDKE \n iHWE 4UCLO - 6yLb6AWKA\n\n";
	PTR_SORTER ptrSorter=0;
	cin>>k;
	switch(k)
	{
	case 1 : ptrSorter=&Sorter::sortByBubble; break;
	case 2 : ptrSorter=&Sorter::sortByLinearChoise; break;
	case 3 : ptrSorter=&Sorter::sortByBoat; break;
	//case 4 : ptrSorter=&Sorter::sortByQuick; break;
	default: ptrSorter=&Sorter::sortByBubble; break;
	}
	Sorter * tempPtrSorter=new Sorter;
	(tempPtrSorter->*ptrSorter)(*this,ptrSort);
	
	
}
// SYSTEM
Group::Group()
{
	m_kilkStudents=0;
	m_ptrMasStudents=0;
	cout<<"Constuctor Group is WORKING"<<endl;
}
Group::Group(int temp)
{
	m_kilkStudents=temp;
	m_ptrMasStudents= new Student [temp];
	cout<<"Constuctor Group with int is WORKING"<<endl;
}
Group::Group(const Group & temp)
{
	cout<<"Copyconstructor is working"<<endl;
	m_kilkStudents=temp.m_kilkStudents;
	m_ptrMasStudents= new Student [m_kilkStudents];
	for(int i=0;i<m_kilkStudents;++i)
		 (*this)[i]=temp.m_ptrMasStudents[i];
}
Group::~Group()
{
	cout<<"destructor Group is working"<<endl;
	delete [m_kilkStudents] m_ptrMasStudents;
}
Group & Group::operator=(const Group & refGroup)
{
	//if (*this!=refGroup)
	{
		m_kilkStudents=refGroup.m_kilkStudents;
		m_ptrMasStudents= new Student [m_kilkStudents];
		for(int i=0;i<m_kilkStudents;++i)
			(*this)[i]=refGroup.m_ptrMasStudents[i];
	}
	return (*this);
}
Student & Group::operator[](int i)
{
	if (i<m_kilkStudents)
		return (*this).m_ptrMasStudents[i];
	Student s;
	return s;
}
Student.h
#ifndef _Student_
#define _Student_
#include <iostream.h>
class Student
{
public:
	/* Accessors   */
	void getName(char *);
	void getSurname(char *);
	void getGroup(char *);
	void getMarks(int *);
	/* Modificators */
	void setName(void);
	void setSurname(void);
	void setGroup(void);
	void setMarks(void);
	/*comparer functions */
	
/*	int sortByName(Student &);
	int sortBySurname(Student &);
	int sortByGroup(Student &);
	int sortByMarks(Student &);*/
//     FRIENDS
	friend class Group;
	friend class Comparer;
	friend ostream & operator <<(ostream & ,Student &);
//    CONSTRUCTOR
	Student();
	~Student();
	//ostream & operator <<(ostream & OS);
private:
	char m_szName[20];
	char m_szSurname[20];
	char m_szGroup[20];
	int m_aiMarks[5];
};
//typedef int(Student::*PTR_sSORT)(Student &);
#endif
Student.cpp
#include <iostream>
#include <string.h>
#include "Student.h"
//    Accessors
void Student :: getName(char * szBuffer)
{
	strcpy(szBuffer, m_szName);
}
void Student::getSurname(char * szBuffer)
{
	strcpy(szBuffer, m_szSurname);
}
void Student::getGroup(char * szBuffer)
{
	strcpy(szBuffer, m_szGroup);
}
void Student::getMarks(int * aiBuffer)
{
	for (int i=0; i<5; ++i)
		aiBuffer[i]=m_aiMarks[i];
}
//     Modificators
void Student::setName(void)
{
	cin.getline(m_szName,20,'\n');
}
void Student::setSurname(void)
{
	cin.getline(m_szSurname,20,'\n');
}
void Student::setGroup(void)
{
	cin.getline(m_szGroup,20,'\n');
}
void Student::setMarks(void)
{
	int temp;
	for(int i=0;i<5;++i)
	{
		cin>>temp;
		m_aiMarks[i]=temp;
	}
}
// COMPARERS
/*int Student::sortByName(Student & s)
{
	if (strcmp(this->m_szName,s.m_szName)>0) return 1;
	return 0;
}
int Student::sortBySurname(Student & s)
{
	if (strcmp(this->m_szSurname,s.m_szSurname)>0) return 1;
	return 0;
}
int Student::sortByGroup(Student & s)
{
	if (strcmp(this->m_szGroup,s.m_szGroup)>0) return 1;
	return 0;
}
int Student::sortByMarks(Student & s)
{
	double ser1=0,ser2=0;
	for(int i=0;i<5;++i)
	{
		ser1+=this->m_aiMarks[i];
		ser2+=s.m_aiMarks[i];
	}
	ser1/=5;
	ser2/=5;
	if (ser1>ser2) return 1;
	return 0;
}*/
// SYSTEM
Student::Student()
{
	m_szName[0]='\0';
	m_szSurname[0]='\0';
	m_szGroup[0]='\0';
	for (int i=0; i<5; ++i)
		m_aiMarks[i]=0;
	cout<<"Constructor Student is working"<<endl;
}
Student::~Student()
{
	cout<<"destructor Student is working"<<endl;
}
/*ostream & Student::operator<<(ostream & OS)
{
	OS<<m_szName<<'\t'<<m_szSurname<<'\t'
		<<m_szGroup<<'\t';
	for (int i=0;i<5;++i)
		OS<<m_aiMarks[i]<<' ';
	OS<<endl;
	return OS;
}*/
ostream & operator <<(ostream & OS,Student & s)
{
	OS<<s.m_szName<<'\t'<<s.m_szSurname<<'\t'
		<<s.m_szGroup<<'\t';
	for (int i=0;i<5;++i)
		OS<<s.m_aiMarks[i]<<' ';
	OS<<endl;
	return OS;
}
Comparer.h
#ifndef _Comparer_
#define _Comparer_
#include "Student.h"
class Comparer
{
public:
	int sortByName(Student & s1,Student & s2);
	int sortBySurname(Student & s1,Student & s2);
	int sortByGroup(Student & s1,Student & s2);
	int sortByMarks(Student & s1,Student & s2);
};
typedef int(Comparer::*PTR_SORT)(Student &,Student &);
#endif
Comparer.cpp
#include <string.h>
#include "Comparer.h"
int Comparer::sortByName(Student & s1,Student & s2)
{
	if (strcmp(s1.m_szName,s2.m_szName)>0) return 1;
	return 0;
}
int Comparer::sortBySurname(Student & s1,Student & s2)
{
	if (strcmp(s1.m_szSurname,s2.m_szSurname)>0) return 1;
	return 0;
}
int Comparer::sortByGroup(Student & s1,Student & s2)
{
	if (strcmp(s1.m_szGroup,s2.m_szGroup)>0) return 1;
	return 0;
}
int Comparer::sortByMarks(Student & s1,Student & s2)
{
	double ser1=0,ser2=0;
	for(int i=0;i<5;++i)
	{
		ser1+=s1.m_aiMarks[i];
		ser2+=s2.m_aiMarks[i];
	}
	ser1/=5;
	ser2/=5;
	if (ser1>ser2) return 1;
	return 0;
}
Sorter.h
#ifndef _Sorter_
#define _Sorter_
#include "Comparer.h"
class Sorter
{
public:
	void sortByBoat(Group &, PTR_SORT);
	void sortByBubble(Group &, PTR_SORT);
	void sortByLinearChoise(Group &, PTR_SORT);
	void sortByQuick(Group &, PTR_SORT);
};
typedef void(Sorter::*PTR_SORTER)(Group &,PTR_SORT); 
#endif
Sorter.cpp
#include "Sorter.h"
#include "Group.h"
void Sorter::sortByBubble(Group & G,PTR_SORT sortFunction)
{
	int n=G.m_kilkStudents;
	int p=1;
	Comparer * tempPtr=new Comparer;
	while((n-1)&&p)
	{
		p=0;
		for(int i=0;i<n-1;++i)
		{
			
			if ((tempPtr->*sortFunction)(G.m_ptrMasStudents[i],G.m_ptrMasStudents[i+1]))
			{
				p=1;
				Student temp=G.m_ptrMasStudents[i];
				G.m_ptrMasStudents[i]=G.m_ptrMasStudents[i+1];
				G.m_ptrMasStudents[i+1]=temp;
			}
		}
		--n;
		
	}
}
void Sorter::sortByLinearChoise(Group & G,PTR_SORT sortFunction)
{
	Comparer * tempPtr=new Comparer;
	for(int i=0; i<G.m_kilkStudents; ++i)
	{
		Student min=G.m_ptrMasStudents[i];
		int minIndex=i;
		for(int j=i+1; j<G.m_kilkStudents; ++j)
		{
			if ((tempPtr->*sortFunction)(min,G.m_ptrMasStudents[j]))
			{
				min=G.m_ptrMasStudents[j];
				minIndex=j;
			}
		}
		G.m_ptrMasStudents[minIndex]=G.m_ptrMasStudents[i];
		G.m_ptrMasStudents[i]=min;
	}
}
void Sorter::sortByBoat(Group & G, PTR_SORT sortFunction)
{
	Comparer * tempPtr=new Comparer;
	for(int i=0; i<G.m_kilkStudents-1; ++i)
	{
		if((tempPtr->*sortFunction)(G.m_ptrMasStudents[i],G.m_ptrMasStudents[i+1]))
		{
			int j=i;
			do
			{
				Student temp=G.m_ptrMasStudents[j];
				G.m_ptrMasStudents[j]=G.m_ptrMasStudents[j+1];
				G.m_ptrMasStudents[j+1]=temp;
				--j;
			}
			while((tempPtr->*sortFunction)(G.m_ptrMasStudents[j],G.m_ptrMasStudents[j+1])&&j);
		}
	}
}
Висновок 
В ході даної лабораторної роботи ми навчилися стврювати класи та оперувати елементами типу клас. Тобто ми навчилися інкапсулювати в класах об’єкти та методи їх обробки та ознайомилися із елементами, які клас може в себе включати, використовувати ці знання для реалізації програм.
Міністерство освіти і науки України
Національний університет “Львівська політехніка”
Інститут прикладної математики та фундаментальних наук
Кафедра прикладної математики
Лабораторна робота №1
з курсу Об’єктно-орієнтоване програмування
Виконав: Остапчук Ю.М.
Група: ПМ-21
Викладач: Пеняк І.О.
Львів-2009
Тема : Побудова класів у С++
Мета : Побудувати клас згідно заданих умов.
Хід роботи :
Згідно умови задачі потрібно було написати клас для представлення функціональності прямокутників з сторонами, паралельними осям координат. Забезпечити можливість переміщення прямокутника, зміни його розмірів, утворення найменшого нового прямокутника, що містить в собі два довільних (є їх об’єднанням) та прямокутника, що є результатом перетину двох заданих. Написати МТ, що дозволяв би перевірити усю задану функціональність (виклик довільних методів класу).
main.cpp
#include <iostream>
#include <conio.h>
#include "Rectangle.h"
void main()
{
	char c = 0;
	while (c != 'e')
	{
		Rectangle R, R1, R2;
		system("cls");
		cout<<"Natusnit' vidpovidny klaviwy:"<<endl
			<<"A: Peremiw4ennja prjamokytnuka."<<endl
		    <<"B: Zmina rozmiriv prjamokytnuka."<<endl
		    <<"C: Stvorennja novogo naimenwogo prjamokytnuka w4o mistut' v sobi dva zadanuh."<<endl
		    <<"D: Stvorennja prjamokytnuka w4o e peretunom dvoh zadanuh."<<endl
		    <<"E: Vujtu z programu."<<endl;
	    c = getch();
		system("cls");
		switch (c)
		{
		case 'a': 
			{
				R.input("R");
				R.move();
				R.output("R");
				getch();
				break;
			};
		case 'b':
			{
				R.input("R");
				R.setsides();
				R.output("R");
				getch();
				break;
			}
		case 'c':
			{
				R1.input("R1");
				R2.input("R2");
				R.createminrec(R1, R2);
				R.output("R");
				getch();
				break;
			};
		case 'd':
			{
				R1.input("R1");
				R2.input("R2");
				R.intersection(R1, R2);
				R.output("R");
				getch();
				break;
			};
		}
	}
}
Rectangle.h
#ifndef _Rectangle_
#define _Rectangle_
#include <iostream.h>
class Rectangle
{
public:
	void output(char[5]);
	void input(char[5]);
	void move(void);
	void setsides(void);
	Rectangle & createminrec(Rectangle &, Rectangle &);
	Rectangle & intersection(Rectangle &, Rectangle &);
	//конструктори
	Rectangle();
	Rectangle(const Rectangle &);
	//деструктор
	~Rectangle();
	Rectangle & operator = (const Rectangle &);//оператор присвоєння нового прямокутник
	Rectangle operator + (const Rectangle &);//утворення найменшого прямокутника з двох заданих
	Rectangle operator * (const Rectangle &);//перетин двох заданих прямокутників
private:  
	int x1;  //масив координат прямокутника - x1, y1, x2, y2
    int y1;
	int x2;
	int y2;
};
#endif
Rectangle.cpp
#include <iostream>
#include <math.h>
#include "Rectangle.h"
void Rectangle::output(char ch[5])
{
	cout<<"Koordunatu prjamokytnuka "<<ch<<": "<<endl; 
	int temp;
	if ((*this).x1 > (*this).x2) {temp = (*this).x1; (*this).x1 = (*this).x2; (*this).x2 = temp;}
	if ((*this).y1 > (*this).y2) {temp = (*this).x1; (*this).x1 = (*this).x2; (*this).x2 = temp;}
	cout<<"x1 = "<<(*this).x1<<endl
		<<"y1 = "<<(*this).y1<<endl
		<<"x2 = "<<(*this).x2<<endl
		<<"y2 = "<<(*this).y2<<endl;
}
void Rectangle::input(char ch[5])
{ 
	cout<<"Vvedit' koordunatu prjamokytnuka "<<ch<<": "<<endl; 
	cout<<"x1 = ";
	cin>>(*this).x1;
	cout<<"y1 = ";
	cin>>(*this).y1;
	cout<<"x2 = ";
	cin>>(*this).x2;
	cout<<"y2 = ";
	cin>>(*this).y2;
	int temp;
	if ((*this).x1 > (*this).x2) {temp = (*this).x1; (*this).x1 = (*this).x2; (*this).x2 = temp;}
	if ((*this).y1 > (*this).y2) {temp = (*this).x1; (*this).x1 = (*this).x2; (*this).x2 = temp;}
}
void Rectangle::move(void)
{
	int x, y;
	cout<<"Vvedit' zmiw4ennja:"<<endl;
	cout<<"dx = ";
	cin>>x;
	cout<<"dy = ";
	cin>>y;
	(*this).x1 += x;
	(*this).y1 += y;
	(*this).x2 += x;
	(*this).y2 += y;
}
void Rectangle::setsides(void)
{
	int x, y;
	cout<<"Vvedit' novi zna4ennja storin:"<<endl;
	cout<<"x = ";
	cin>>x;
	cout<<"y = ";
	cin>>y;
	if (x < 0) x = -x;
	if (y < 0) y = -y;
	(*this).x2 = (*this).x1 + x;
	(*this).y2 = (*this).y1 + y;
}
Rectangle & Rectangle::createminrec(Rectangle & R1, Rectangle & R2)
{
	if (R1.x1 < R2.x1) (*this).x1 = R1.x1;
	else (*this).x1 = R2.x1;
	if (R1.y1 < R2.y1) (*this).y1 = R1.y1;
	else (*this).y1 = R2.y1;
	if (R1.x2 < R2.x2) (*this).x2 = R2.x2;
	else (*this).x2 = R1.x2;
	if (R1.y2 < R2.x2) (*this).y2 = R2.y2;
	else (*this).y2 = R1.y2;
	return (*this);
}
Rectangle & Rectangle::intersection(Rectangle & R1, Rectangle & R2)
{
	(*this).x1 = (*this).x2 = (*this).y1 = (*this).y2 = 0;
	if ((R2.x1 >= R1.x2)||(R2.y1 >= R1.y2)||(R2.x2 <= R1.x1)||(R2.y2 <= R2.y1))
		return (*this);
	if (R2.x1 < R1.x1) (*this).x1 = R1.x1;
		else (*this).x1 = R2.x1;
	if (R2.x2 < R1.x2) (*this).x2 = R2.x2;
		else (*this).x2 = R1.x2;
	if (R2.y1 < R1.y1) (*this).y1 = R1.y1;
		else (*this).y1 = R2.y1;
	if (R2.y2 < R1.y2) (*this).y2 = R2.y2;
		else (*this).y2 = R1.y2;
		return (*this);
}
//конструктори
Rectangle::Rectangle()
{
	x1 = y1 = x2 = y2 = 0;
	//cout<<"Constructor Rectangle is working..."<<endl;
}
Rectangle::Rectangle(const Rectangle & R)
{
	//cout<<"Copyconstructor is working..."<<endl;
	(*this).x1 = R.x1;
	(*this).x2 = R.x2;
	(*this).y1 = R.y1;
	(*this).y2 = R.y2;
}
//деструктор
Rectangle::~Rectangle()
{
	//cout<<"Destructor is working..."<<endl;
}
Rectangle & Rectangle::operator = (const Rectangle & R)//оператор присвоєння нового прямокутник
{
	(*this).x1 = R.x1;
	(*this).x2 = R.x2;
	(*this).y1 = R.y1;
	(*this).y2 = R.y2;
	return (*this);
}
Rectangle Rectangle::operator + (const Rectangle & R1)//утворення найменшого прямокутника з двох заданих
{
	Rectangle R;
	if ((*this).x1 < R1.x1) R.x1 = (*this).x1;
	else R.x1 = R1.x1;
    if ((*this).y1 < R1.y1) R.y1 = (*this).y1;
	else R.y1 = R1.y1;
	if ((*this).x2 < R1.x2) R.x2 = R1.x2;
	else R.x2 = R1.x2;
	if ((*this).y2 < R1.x2) R.y2 = R1.y2;
	else R.y2 = R1.y2;
	return R;
}
Rectangle Rectangle::operator * (const Rectangle & R1)//перетин двох заданих прямокутників
{
	
	Rectangle R;
	R.x1 = R.x2 = R.y1 = R.y2 = 0;
	if ((R1.x1 >= (*this).x2)||(R1.y1 >= (*this).y2)||(R1.x2 <= (*this).x1)||(R1.y2 <= R1.y1))
		return R;
	if (R1.x1 < (*this).x1) R.x1 = (*this).x1;
		else R.x1 = R1.x1;
	if (R1.x2 < (*this).x2) R.x2 = R1.x2;
		else R.x2 = (*this).x2;
	if (R1.y1 < (*this).y1) R.y1 = (*this).y1;
		else R.y1 = R1.y1;
	if (R1.y2 < (*this).y2) R.y2 = R1.y2;
		else R.y2 = (*this).y2;
		return R;
}
Висновок: на цій лабораторній роботі я вдосконалив свої навики у створенні класів в С++, організації їх конструкторів, деструкторів, перегружених операцій та операторів, полів і методів. А також я ще більше освоїв основні принципи ООП (принаймні один з трьох основних принципів ООП – інкапсуляцію).
Міністерство освіти і науки України
Національний університет “Львівська політехніка”
Інститут прикладної математики та фундаментальних наук
Кафедра прикладної математики
Лабораторна робота №2
з курсу Об’єктно-орієнтоване програмування
Виконав: Остапчук Ю.М.
Група: ПМ-21
Викладач: Пеняк І.О.
Львів-2009
Тема: наслідування класів у С++
Мета: навчитися будувати наслідування класів у С++
Хід роботи :
Потрібно написати базовий клас – Стрічка.
Обов’язковими полями повинні бути :
Вказівник на char — зберігає адресу динамічної виділеної пам’яті для символів стрічки. 
Значення типу int — зберігає і-цію про довжину стрічки в байтах.
Обов’язковими методами  повинні бути : 
Конструктор без параметрів.
Конструктор, що приймає С-стрічку (закінчується нуль-байтом).
Конструктор, що приймає в якості параметра символ.
Конструктор копіювання.
Метод для отримання довжини стрічки.
Очистка стрічки (зробити стрічку пустою)
Деструктор
Написати похідний від класу Стрічка – клас КОМПЛЕКСНЕ_ЧИСЛО. 
Стрічки даного класу складені з двох полів, розділених символом «і» : перше поле задає значення дійсної частини числа, а друге — комплексної. Кожне поле може містити лише символи десяткови цифр та символи «+» і «-» . Символи «-» та «+» можуть бути лише в першій позиції стрічки; при відсутності будь-якого з вищеперелічених символів – по замовчуванню приймається «+».Якщо «народжувальна» «комплексна стрічка» в момент ініціалізації прийматиме стрічку з недопустимими для даної логіки символами, - то кінцевий об’єкт - КОМПЛЕКСНЕ_ЧИСЛО – ініціалізується порожнім значенням.
Приклади валідних (допустимих) стрічок : 33і12   -7і100   +5і21
Обов’язковими методами  повинні бути : 
Конструктор без параметрів.
Конструктор, що приймає С-стрічку (закінчується нуль-байтом).
Конструктор копіювання.
Деструктор
Перевизначити такі операції :
Присвоєння (=).
Операція (==) – перевірка на рівність.
Множення (*) – множення за правилами дій над полем комплексних чисел.
Розробник може добавляти в клас додаткові поля та методи (з обгрунтуванням їх необхідності та доцільності). 
Написати тестову програму, яка 
Динамічно виділяє масив вказівників на базовий клас
В режимі діалога заповнює цей масив вказівниками на екземпляри похідних класів (причому всі об’єкти створюються в «хіпі» з заданням початкових (вхідних параметрів) ).
Для створених об’єктів похідних класів забезпечити перевірку всіх утворених методів з виводом результатів на екран і/або в файл (лог).
main.cpp
#include <conio.h>
#include <vector>
#include "string1.h"
#include "complex.h"
void main()
{
	String1** st= new String1*[2];
	char a;
	for (int i=0;i<2;++i)
	{
		cout<<"Vvedit' "<<i+1<<"-e komplexne 4uslo v formati '__i__':"<<endl;
		vector <char> av;
		do
		{
			cin.get(a);
			av.push_back(a);
		}
		while(a!='\n'); 
		char * str = new char[av.size()];
		for(int j=0; av[j]!=av.back(); ++j)
			str[j]=av[j];
		str[j]='\0';
		//cout<<str<<" "<<j<<endl;
		st[i]=new Complex(str);
		cout<<(*st[i])<<endl;
	}
	cout<<endl;
	*st[0]=*st[1];
	cout<<*st[0]<<endl<<*st[1];
}
string1.h
#ifndef _STRING1_
#define _STRING1_
#include<iostream>
using namespace std;
class String1
{
protected:
	char* str;
	int size;
public:
	virtual void operator*(String1 &st){};
	String1 ();
	String1 (char*);
	String1 (String1&);
	String1 (char);
	virtual ~String1();
	virtual String1& operator= (const String1&);
	int getSize();
	void zeroStr();
	virtual bool operator ==(const String1&);
	//char* getStr();
	///int getSize();
	//void setStr(char*);
	//void setSize(int);
	friend ostream& operator<< (ostream& os, String1 st)
	{
		if (st.str==NULL)
		{
			os<<st.size<<endl;
			os<<'\n';
		}
		else
		{
			os<<st.size<<endl;
			os<<st.str<<endl;
		}
		return os;
	}
};
#endif
string1.cpp
#include <string>
#include "string1.h"
String1::String1 (String1& st)
{
	cout<<"copy constructor String1"<<endl;
	size=st.size;
	if (st.str==NULL) str=NULL;
	else{
	str= new char [strlen(st.str)+1];
	strcpy(str,st.str);}
}
String1::~String1()
{
	cout<<"destructor String1"<<endl;
	delete []str;
}
String1& String1::operator = (const String1& st)
{
	cout<<"operator = String1"<<endl;
	if (this!=&st)
	{
		delete []str;
		size=st.size;
		str= new char [strlen(st.str)+1];
		strcpy(str, st.str);
	}
	return (*this);
}
String1::String1 (char* st)
{
	cout<<"constructor String1(char*)"<<endl;
	size= (strlen(st)+1)*sizeof(char);
	str=new char [strlen(st)+1];
	strcpy(str,st);
}
String1::String1 ()
{
	cout<<"constructor String1"<<endl;
	str=NULL;
	size=0;
}
String1::String1 (char t)
{
	cout<<"constructor String1(char)"<<endl;
	size=sizeof(t);
	str=new char[2];
	str[0]=(&t)[0];
	str[1]='\0';
}
int String1::getSize()
{
	return size;
}
void String1::zeroStr()
{
	strcpy(str,"");
	size=sizeof(char);
}
bool String1::operator ==(const String1& st)
{
	cout<<"operator ==(const String1& st)"<<endl;
	bool pr;
	if(str==NULL && st.str==NULL)
		pr=true;
	else if(str==NULL || st.str==NULL) 
			pr=false;
		else if(!strcmp(str,st.str)) 
			pr=true;
		else 
			pr=false;
		return pr;
}
complex.h
#ifndef _COMPLEX_
#define _COMPLEX_
#include "string1.h"
class Complex:public String1
{
public:
	Complex();
	Complex(char *);
	Complex(Complex&);
	~Complex();
	Complex& operator=(const Complex&);
	bool operator == (Complex&);
	void getInt(char*, int&, int&);
	bool perevirka (char*);
	Complex operator*(Complex& );
};
#endif
complex.cpp
#include <string>
#include "complex.h"
Complex::Complex()
{
	cout<<"constructor complex()"<<endl;
	str=new char[4];
	strcpy(str,"0i0");
	size=(strlen(str)+1)*sizeof(char);
}
Complex::Complex(char* st)
{
	cout<<"constructor Complex(char*)"<<endl;
	if(perevirka (st))
	{
		delete []str;
		str=new char[strlen(st)+1];
		strcpy(str,st);
		size=(strlen(st)+1)*sizeof(char);
	}
	else
	{
		delete []str;
		str=new char[4];
		strcpy(str,"0i0");
		size=(strlen(str)+1)*sizeof(char);
	}
}
Complex::Complex(Complex& c)
{
	cout<<"constructor copy Complex"<<endl;
	size=c.size;
	str=new char[strlen(c.str)+1];
	strcpy(str,c.str);
}
Complex::~Complex()
{
	cout<<"destructor Complex"<<endl;
}
Complex& Complex::operator=(const Complex&c)
{
	cout<<"operator= Complex"<<endl;
	if(this!=&c)
	{
		delete[]str;
		str=new char[strlen(c.str)+1];
		strcpy(str,c.str);
		size=c.size;
	}
	return (*this);
}
bool Complex::operator ==(Complex&c)
{
	cout<<"operator ==(Complex&c)"<<endl;
	char*st;
	if (strlen(str)>strlen(c.str))
		 st= new char[strlen(str)];
	else st=new char[strlen(c.str)];
	bool pr=false;
	int j,k,t,r;
	this->getInt(st,j,k);
	c.getInt(st,t,r);
	if(j==t && k==r) pr=true;
	delete []st;
	if(pr==true) return pr;
	else return pr; 
}
void Complex::getInt(char* st, int& j, int& k)
{
	for(int i=0;str[i]!='i';++i)
		st[i]=str[i];
	st[i]='\0';
	j=atoi(st);
	int r;
	for(++i,r=0;str[i]!='\0';++i,++r)
		st[r]=str[i];
	st[r]='\0';
	k=atoi(st);
	
}
bool Complex::perevirka(char* st)
{
	bool pr,pr1=true;
	int i;
	char a[]={'+','-','i','0','1','2','3','4','5','6','7','8','9'};
		
	if(st[0]==a[0]||st[0]==a[1])
	{
		if(st[1]=='i') pr1=false;
		for( i=1;st[i]!='i';++i)
		{
			pr=true;
			for(int j=3;j<13;++j)
				if(st[i]==a[j]) pr=false;
			if (pr==true)
			{
			
				pr1=false;
				break;
			}
		}
	}
	else
	{
		if(st[0]=='i') pr1=false;
		for( i=0;st[i]!='i';++i)
		{
			pr=true;
			for(int j=3;j<13;++j)
				if(st[i]==a[j]) pr=false;
			if (pr==true)
			{
		
				pr1=false;
				break;
			}
		}
	}
		
	i+=1;
	
	if(st[i]==a[0]||st[i]==a[1])
	{
		if(st[i+1]=='\0') pr1=false;
		for(i+=1;st[i]!='\0';++i)
		{
			pr=true;
			for(int j=3;j<13;++j)
				if(st[i]==a[j]) pr=false;
			if (pr==true)
			{
			
				pr1=false;
				break;
			}				
		}
	}
	else
	{
		if(st[i]=='\0') pr1=false;
		for(;st[i]!='\0';++i)
		{
			pr=true;
			for(int j=3;j<13;++j)
				if(st[i]==a[j]) pr=false;
			if (pr==true)
			{
			
				pr1=false;
				break;
			}
		}
	}
	return pr1;
}
Complex Complex::operator*( Complex& c)
{
	char*st,*st1;
		 st= new char[strlen(str)+strlen(c.str)];
		 st1=new char[strlen(str)+strlen(c.str)];
	int j,k,t,r;
	this->getInt(st,j,k);
	c.getInt(st,t,r);
	cout<<"j="<<j<<"k="<<k<<"t="<<t<<"r="<<r<<endl;
	int temp,tempi;
	temp=(j*t-k*r);
	tempi=(j*r-k*t);
	itoa(temp,st,10);
	strcat(st,"i");
	itoa(tempi,st1,10);
	strcat(st,st1);
	delete[]st1;
	Complex z(st);
	delete []st;
	return z;
}
Висновок
 
В ході даної лабораторної роботи ми навчилися будувати 
наслідування класів у С++.  Використали принцип ієрархічного меню.