/*
Определить конструктор для инициализации полей по умолчанию.
Определить конструктор копирования и деструктор. Написать тестовый пример.
Строковые поля описать как указатели, при этом в конструкторе должно производиться не тупое присвоение указателей, а копирование строк.
Также внести в класс тестовую функцию - изменяющую первую букву отчества на 'Ы' для проверки корректности конструктора.
*/
/*
codeby.net
Autor: DarkKnight125
*/
#include <iostream>
using namespace std;
//Класс Студент
struct TStudent
{
private:
char *LastName; //Будем использовать указатели но определимся по размеру Фамилия не более 32 символов
char *FirstName; //Имя не более 16 символов
char *Patronimyc; //Отчество не более 32х символов
int Born; //Год рождения
char *Group; //Группа не более 10 символов
public:
TStudent(); //Конструктор класса по умолчанию *просто выделим память под все поля
~TStudent(); //Деструтор класса
TStudent (TStudent& Student); //Конструктор копирования по умолчанию
TStudent operator= (TStudent& Student); //Оператор присвоения
void SetLastName (char* sLastName); //Присваивание Фамилии
void SetFirstName (char* sFirstName);//Присваивание Имени
void SetPatronimyc (char* sPatronimyc);//Приваивание отчества
char* GetLastName(void); //Получение указателя на Фамилию
char* GetFirstName(void);//Получение указателя на имя
char* GetPatronimyc(void); //Получение указателя на Отчество
int& BornDate(void); //Изменение даты рождения
//Дружественная функция перезагрузки вывода в стандартный поток вывода (STDOUT)
friend ostream& operator<< (ostream& out, TStudent Student)
{
out<<"Фамилия : "<< Student.LastName<< endl;
out<<"Имя : "<< Student.FirstName<< endl;
out<<"Отчество : "<< Student.Patronimyc<< endl;
out<<"Год рождения : "<< Student.Born<< endl<< endl;
return out;
}
};
//Конструктор по умолчанию *просто выделим память под все поля
TStudent::TStudent()
{
//Выделим памяти для Фамилии, Имени и Отчества на которые указывают их указатели char*
LastName = new char[32+1];
memset(LastName,0,33);
FirstName = new char[16+1];
memset(FirstName,0,17);
Patronimyc = new char[32+1];
memset(Patronimyc, 0,33);
};
//Конструктор копирования по-умолчанию
TStudent::TStudent (TStudent& Student)
{
//В конструкторе копирования, так же выделим память на которые указывают указатели
LastName = new char[32+1];
FirstName = new char[16+1];
Patronimyc = new char[32+1];
//И скопируем в них значения из объекта класса на базе которого мы создаем объект путем копирования
strcpy(LastName, Student.LastName);
strcpy(FirstName, Student.FirstName);
strcpy(Patronimyc, Student.Patronimyc);
Born = Student.Born;
}
//Перезагрузка оператора присвоения
TStudent TStudent::operator= (TStudent& Student) //Оператор присвоения
{
strcpy(LastName, Student.LastName);
strcpy(FirstName, Student.FirstName);
strcpy(Patronimyc, Student.Patronimyc);
Born = Student.Born;
return *this;
}
//Присваивание Фамилии
void TStudent::SetLastName (char* sLastName)
{
strncpy(LastName,sLastName,32); //Скопируем с проверкой на длину что бы не было переполнения
}
//Присваивание Имени
void TStudent::SetFirstName (char* sFirstName)
{
strncpy(FirstName,sFirstName,16); //Скопируем с проверкой на длину что бы не было переполнения
}
//Приваивание отчества
void TStudent::SetPatronimyc (char* sPatronimyc)
{
strncpy(Patronimyc, sPatronimyc,32); //Скопируем с проверкой на длину что бы не было переполнения
}
//Получение указателя на Фамилию
char* TStudent::GetLastName(void) //Реализация таких функций-класса не самый лучший вариант, но если этого требует задание, то ничего с этим не поделаешь
{ //По хорошему, возрат таких функций должен быть const char*, дабы исключить возможность изменения, но нам нужно исправить
return LastName; //Первый символ на 'Ы' по заданию, поэтому оставляем ее так...
}
//Получение указателя на имя
char* TStudent::GetFirstName(void) //Аналогично прошлой
{
return FirstName;
}
//Получение указателя на Отчество
char* TStudent::GetPatronimyc(void) //Так же аналогично
{
return Patronimyc;
}
//Возврат ссылки на дату рождения
int& TStudent::BornDate(void) //Возвращаем ссылку на ДатуРождения
{
return Born;
}
//Деструктор класса
TStudent::~TStudent()
{
delete[] LastName; //Отчистим память которую мы выделили
delete[] FirstName;//Отчистим память которую мы выделили
delete[] Patronimyc;//Отчистим память которую мы выделили
}
//Точка входа (главная функция)
void main(void)
{
setlocale(LC_ALL,"Russian");
TStudent D1; //Создади объект класса конструктором по умолчанию
//Заполним его
D1.SetFirstName("Иван");
D1.SetLastName("Иванов");
D1.SetPatronimyc("Иванович");
D1.BornDate() = 1985;
cout<<"Конструктор по умолчанию + заполнение полей:"<< endl;
cout<< D1; //Выведим на экран
//Создадим объект констуктором копирования
TStudent D2(D1);
//Если все было реализованно верно, то указатели D2 не должны быть равны указателям D1
//Проверим это следующим образом
cout<<"Проверка конструктора копирования по умолчанию :"<< endl;
cout<<D2; //Выведим на экран D2
D1.GetLastName()[0] ='Ы';//Изменим первый символ фамилии D1 на 'Ы'
cout<<D1<< D2; //Выведим на экран сначало D1 и D2 (результаты должны быть разными
}