Главная страница
Навигация по странице:

  • Вариант №9 Задание

  • ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ. Отчет Лаб 2. Лабораторная работа 2 по дисциплине объектноориентированное программирование Выполнил студент специальности 27. 03. 04


    Скачать 0.52 Mb.
    НазваниеЛабораторная работа 2 по дисциплине объектноориентированное программирование Выполнил студент специальности 27. 03. 04
    АнкорОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ
    Дата05.09.2022
    Размер0.52 Mb.
    Формат файлаdocx
    Имя файлаОтчет Лаб 2.docx
    ТипЛабораторная работа
    #662429



    Министерство науки и высшего образования Российской Федерации

    Федеральное государственное бюджетное образовательное учреждение

    высшего образования

    ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ

    УПРАВЛЕНИЯ И РАДИОЭЛЕКТРОНИКИ (ТУСУР)

    Лабораторная работа № 2

    по дисциплине «ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ»


    Выполнил студент:

    специальности 27.03.04

    Жуков Сергей Андреевич


    2022 год

    Содержание
    1.Задание………………………………………………………………………………3

    2.Работа программы…………………………………………………………………..7

    3.Листинг программ………………………………………………………………8-16

    4.Заключение………………………………………………………………………..16

    Вариант №9

    Задание: Создание динамического массива объектов. Деструктор объекта. Два типа полиморфизма: принудительное приведение типа, перегрузка функций и перегрузка операторов (унарных и бинарных).


    1. В среде программирования на С++ создайте консольный проект с именем LAB2 в каталоге LAB2.

    2. Переименуйте файл main.h из предыдущей лабораторной в person.h. Создайте файл person.cpp, и включите в проект эти два файла. Переместите конструктор и функции объекта Person из main.cpp в файл person.cpp. Таким образом, файл person.h содержит описание объекта Person, а файл person.cpp – реализацию объекта Person.





    1. Включите в проект файл main.cpp и очистите тело функции main().

    2. Определите объект Group, который будет содержать динамический массив объектов Person. Создайте два файла group.h и group.cpp и включите их в проект.

    3. В файле group.h определите с помощью ключевого слова classобъект Group.

    Данные объекта:
    размер массива (целый тип)

    указатель на массив (тип Person* )



    Пусть данные имеют закрытый уровень доступа (private).

    1. Опишите конструктор объекта с одним аргументом – размер массива (целый тип) и деструктор объекта.

    2. Откройте файл group.cpp. С помощью директивы #includeвключите необходимые заголовочные файлы.

    3. Определите конструктор объекта Group. В теле конструктора проинициализируйте данные объекта, т.е. проинициализируйте размер массива значением аргумента конструктора и выделите динамическую память под массив с помощью строки кода:


    указатель на массив = new Person[размер массива].


    1. В деструкторе объекта освободите память, занимаемую массивом, с помощью строки кода


    delete [] указатель на массив.
    Таким образом, мы создали объект Group, который содержит массив объектов Person.

    1. Определим открытые (public) методы для объекта Group. Напишите функцию void Group::Print(), которая выводит в цикле for все записи массива на экран. В теле цикла примените ранее написанную функцию Print() для объекта Person.

    2. Напишите функцию int Group::Size(), которая возвращает размер массива.

    3. Напишите функции void PutPerson(int i, Person& man); и Person& GetPerson(int i);, первая функция заносит объект man типа Person в i-й элемент массива, вторая функция возвращает объект типа Person из i-го элемента массива.

    4. Заполните массив данными и затем выведите их на экран. Для этого в теле функции int main() сначала определите массив имен, которые будут заносится в поле ФИО объекта Person, например,


    char names[5][25] = {"A", "B", "C", "D", "E"};.
    Затем создайте объект с именем group типа Group размером пять записей, т.е. Group group(5);.

    1. Ниже с помощью цикла for заполните массив данными. Для этого в теле цикла создайте объект Person, проинициализировав всеего данные, и с помощью функции PutPerson занесите объект в массив.

    2. Выведите массив на экран с помощью строки кода: group.Print();. Получилось? Если да, то вы научились создавать динамический массив объектов, определять функции работы с таким массивом и выводить его на экран.

    3. В этой части лабораторной работы изучим первые два типа полиморфизма – это: а) принудительное приведение типа; б) перегрузка функций и операторов.

    4. Напишите функцию приведения типа. Для этого с помощью ключевого слова operator напишите функцию объекта Person, которая преобразует тип Person вdouble. Пусть функция возвращает возраст человека, например,


    Person::operator double() {returnthis->Age; }.
    Что означает ключевое слово this?

    1. Проверьте функцию преобразования типа. В функции int main() далее определите переменную double и присвойте ей объект Person, например,


    double age = group.GetPerson(2);.
    Т.е. совершается неявное преобразование из типа Person в тип double при обращении к объекту. Выведите значение переменной на экран.

    1. Перегруженные функции имеют одинаковое название, но разный возвращаемый тип или/и разный список аргументов. Определим в объекте Group две функции с одинаковым именем, например double Age(); и double Age(int limit);. Первая функция пусть возвращает средний возраст группы людей, а вторая функция пусть возвращает средний возраст людей в группе, возраст которыхне больше некоторого граничного значения limit. Функции отличаются списком аргументов.

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

    3. Перегрузите оператор индексирования. Если раньше, чтобы обратиться к элементу массива, нам необходимо было вызывать функцию GetPerson, то, определив оператор индексирования, мы будем использовать только квадратные скобки. Сравните две строки кода:


    Person man = group.GetPerson(2);

    Person man = group[2];
    В объекте Group с помощью ключевого слова operator определите оператор индексирования, например:
    Person& Group::operator[](int i).
    В теле оператора напишите код, возвращающий i-тый элемент массива, т.е. объект Person

    1. Выведите на экран с помощью оператора индексирования любой один элемент массива group, например третий.

    2. Перегрузим бинарный оператор, например оператор сложения (+) для объекта Person. Пусть оператор сложения будет возвращать суммарный возраст двух человек. Опишем в объекте Person данный оператор как дружественную функцию с помощью ключевого слова friend, например:



    friend double operator+(Person& p1, Person& p2);
    Эта строка кода означает, что оператор сложения не принадлежит объекту, но ему доступны все закрытые данные и методы объекта.

    В файле person.cpp определите оператор сложения, например:


    doubleoperator + (Person& p1, Person& p2)

    { return (p1.Age + p2.Age); }
    Здесь мы напрямую обращаемся к закрытому полю Age объекта Person.

    1. Проверим работу оператора с помощью следующих строк кода:

    double sum = group[1] + group[3];

    cout << sum << endl
    Работа программы:



    Листинг программы :
    Person.h
    #include
    class Person

    {

    public: // данные имеют открытый уровень доступа

    //конструктор объекта, аргументы которого инициализируют все его данные

    Person(int number, const char* fio, int man_woman, double age);

    //конструктор объекта по умолчанию

    Person();

    //функция вывода данных на экран

    void Print() const;

    //функция ввода данных в объект с клавиатуры

    void Input();

    //приведение к типу double. возвращает возраст

    operator double() const;
    //получить значение номера

    int GetNumber() const;

    //получить фио

    const char* GetFio() const;

    //проверить женщина ли это

    int IsWoman() const;

    //проверить мужчина ли это

    int IsMan() const;

    //получить возвраст

    double GetAge() const;

    //оператор сравнения двух объектов типа Person

    bool operator==(Person const& other) const;

    //оператор неравенства

    bool operator!=(Person const& other) const;

    //оператор вывода в поток (дружественная функция)

    friend ostream& operator <<(ostream& os, Person const& pers);
    private: // данные имеют закрытый уровень доступа

    int _number; // номер человека

    char _fio[64];// Ф.И.О.

    int _man_woman;// пол

    double _age; // возраст

    };


    Person.cpp

    #include

    #include

    #include

    #include "person.h"
    //конструктор объекта, аргументы которого инициализируют все его данные

    Person::Person(int number, const char* fio, int man_woman, double age)

    : _number(number),_man_woman(man_woman),_age(age)//установка простых полей

    {

    strncpy(_fio,fio,sizeof(_fio));//копирование Ф.И.О.

    }

    //конструктор объекта по умолчанию

    Person::Person()

    : _number(0),_man_woman(0),_age(0)//установка простых полей

    {

    _fio[0] = 0;//т.к. первый символ равен 0,в Ф.И.О. пустая строка

    }

    //функция вывода данных на экран

    void Person::Print() const

    {

    cout << *this;//вызывает оператор <<

    }
    //функция ввода данных в объект с клавиатуры

    void Person::Input()

    {

    cout << "Input new person data:" << endl;//приглашение ввести данные о новом человеке

    cout << "\tInput number: ";//приглашение ввести номер человека

    cin >> _number;//ввод номера

    cout << "\tInput name: ";//приглашение ввести Ф.И.О. человека

    cin.ignore(); //пропуск символа конца строки

    cin.getline(_fio,sizeof(_fio),'\n');//ввод Ф.И.О. человека

    cout << "\tInput age: ";//приглашение ввести возраст

    cin >> _age;//ввод возраста

    cout << "\tInput sex(0 - man, else - woman): ";//приглашение ввести пол

    cin >> _man_woman;//ввод пола

    }
    //приведение к типу double. возвращает возраст

    Person::operator double() const

    {

    return _age;

    }
    //получить значение номера

    int Person::GetNumber() const

    {

    return _number;

    }

    //получить фио

    const char* Person::GetFio() const

    {

    return _fio;

    }

    //проверить женщина ли это

    int Person::IsWoman() const

    {

    return _man_woman;

    }
    //проверить мужчина ли это

    int Person::IsMan() const

    {

    return !_man_woman;

    }
    //получить возвраст

    double Person::GetAge() const

    {

    return _age;

    }
    //оператор сравнения двух объектов типа Person

    bool Person::operator==(Person const& other) const

    {

    return _number == other._number &&

    _age == other._age &&

    _man_woman == other._man_woman &&

    0 == strcmp(_fio, other._fio);

    }
    //оператор неравенства

    bool Person::operator!=(Person const& other) const

    {

    return !(*this == other);//инвертируем результат оператора ==

    }
    //оператор вывода в поток (дружественная функция)

    ostream& operator <<(ostream& os, Person const& pers)

    {

    os << "Num: " << pers._number << "\tName: " << pers._fio << "\tAge: "

    << pers._age << "\tSex: " << (pers._man_woman?'W':'M') << endl;

    return os;

    }
    Main.cpp
    #include "group.h"

    #include

    #include
    //главная функция

    int main()

    {

    Group g1(5);//группа 1

    g1.PutPerson(0,Person(1,"Roman Romanov ", 0, 35.0));

    g1.PutPerson(1,Person(2,"Stepan Stepanov ", 0, 25.0));

    g1.PutPerson(2,Person(3,"Petr Petrov ", 0, 60.0));

    g1.PutPerson(3,Person(4,"Ivan Ivanov ", 1, 22.0));

    g1.PutPerson(4,Person(5,"Maksim Maksimov ", 0, 21.0));
    //1. демонстрация работы оператора <<

    //вывод группы на экран

    cout << "Group #1\n" << g1 << endl;
    //2. демонстрация работы оператора сравнения групп

    //создаём копию группы 1

    Group g2(g1.Size());

    for(unsigned i=0;i
    g2.PutPerson(i,g1[i]);//копируем поэлементно.

    //вывод группы на экран

    cout << "Group #2\n" << g2 << endl;

    //вывод результата сравнения

    cout << "G1 is equal to G2: it is " << ((g1 == g2)?"true":"false") << endl << endl;

    g2.PutPerson(3, Person(6,"Vasya ", 0, 40));

    //теперь группы должны отличаться

    cout << "Group #2\n" << g2 << endl;

    cout << "G1 is equal to G2: it is " << ((g1 == g2)?"true":"false") << endl << endl;
    //3. демонстрация функций поиска в группе

    Person* result = 0;

    const int NUMBER = 2;

    const int WRONGNUMBER = 33;

    result = g1.FindPerson(NUMBER);//по номеру

    cout << "Search for number "<
    if(result)

    cout << *result;

    else

    cout << "" << endl;

    result = g1.FindPerson(WRONGNUMBER);//по номеру (которого нет)

    cout << "Search for number "<
    if(result)

    cout << *result;

    else

    cout << "" << endl;

    const double AGE = 22.0;

    const double WRONGAGE = 33.3;

    result = g1.FindPerson(AGE);//по возрасту

    cout << "Search for age "<
    if(result)

    cout << *result;

    else

    cout << "" << endl;

    result = g1.FindPerson(WRONGAGE);//по возрасту (которого нет)

    cout << "Search for age "<
    if(result)

    cout << *result;

    else

    cout << "" << endl;

    const char* const NAME = "Maksim Maksimov ";

    const char* const WRONGNAME = "NEKTO";

    result = g1.FindPerson(NAME);//по возрасту

    cout << "Search for name \""<
    if(result)

    cout << *result;

    else

    cout << "" << endl;

    result = g1.FindPerson(WRONGNAME);//по имени (которого нет)

    cout << "Search for name \""<
    if(result)

    cout << *result;

    else

    cout << "" << endl;


    cout << "Press any key for exit..." << endl;

    getch();//ожидание нажатия любой клавиши

    return EXIT_SUCCESS;//завершение работы программы

    }

    GROUP.h
    #ifndef GROUP_H

    #define GROUP_H
    #include "person.h"
    //класс "Группа"

    class Group

    {

    private:

    unsigned _size;//размер массива

    Person* _persons;//указатель на массив элементов типа Person
    public: //секция открытых методов

    //конструктор с указанием размера

    Group(unsigned size);

    //деструктор

    Group();

    //выводит данные о всех хранимых элементах

    void Print() const;

    //возвращает размер массива

    unsigned Size() const;

    //вставить элемента в указанную позицию

    void PutPerson(int idx, Person const& man);

    //получить ссылки на элемент в указанной позиции

    Person const& GetPerson(int idx) const;

    //средний возраст

    double Age() const;

    //средний возраст среди лиц не старше limit

    double Age(int limit) const;

    //перегруженный оператор []

    //получение ссылки на элемент в указанной позиции

    Person& operator[](int idx);
    //оператор сравнения двух групп

    bool operator==(Group const& other) const;

    //искать по номеру

    Person* FindPerson(int number);

    //искать по имени

    Person* FindPerson(const char* fio);

    //искать по возрасту

    Person* FindPerson(double age);

    };
    //оператор вывода в поток

    ostream& operator <<(ostream& os, Group const& g);
    #endif

    Group.cpp
    //Файл с реализацией методов класса Group

    #include "group.h"

    #include
    //конструктор

    // size - размер создаваемого массива.

    Group::Group(unsigned size)

    : _size(size) //запоминаем размер массива

    , _persons(size ? new Person[size] : 0) //выделяем память, если надо

    {}
    //деструктор

    Group::Group()

    {

    delete[] _persons;//освобождение памяти из-под массива

    }
    //выводит данные о всех хранимых элементах

    void Group::Print() const

    {

    cout << *this;//искользуем оператор <<

    }
    //возвращает размера массива

    unsigned Group::Size() const

    {

    return _size;

    }
    //вставить элемента в указанную позицию

    void Group::PutPerson(int index, Person const& man)

    {

    _persons[index] = man;

    }
    //получить ссылки на элемент в указанной позиции

    Person const& Group::GetPerson(int index) const

    {

    return _persons[index];

    }
    //получить средний возраст в группе

    double Group::Age() const

    {

    double sum = 0;//сумма

    for (unsigned i = 0; i < _size; ++i)

    sum += _persons[i];//вызывается оператор приведения к double

    return _size ? sum/_size : 0;
    }

    //средний возраст вреди лиц не старше limit

    double Group::Age(int limit) const

    {

    double sum = 0;//сумма всех возрастов

    unsigned count = 0;//количество подсчитанных элементов

    for (unsigned i = 0; i < _size; ++i)

    {

    if(_persons[i] <= limit)//сравниваем с ограничением по возрасту

    {

    sum += _persons[i];

    ++count;

    }

    }

    return count ? sum/count : 0;

    }
    //перегруженный оператор [] - получение ссылки на элемент в указанной позиции

    Person& Group::operator[](int index)

    {

    return _persons[index];

    }

    //оператор сравнения двух групп

    bool Group::operator==(Group const& other) const

    {

    if(_size != other._size)

    return false;//не равны размеры

    for(unsigned i = 0; i < _size; ++i)

    if(_persons[i] != other._persons[i])//используем оператор != из класса Person

    return false;//найдены неравные элементы

    return true;//все элементы оказались равны

    }
    //искать по номеру

    Person* Group::FindPerson(int number)

    {

    for(unsigned i = 0; i < _size; ++i)

    if(number == _persons[i].GetNumber())

    return _persons+i;

    return 0;//ничего не найдено

    }

    //искать по имени

    Person* Group::FindPerson(const char* fio)

    {

    for(unsigned i = 0; i < _size; ++i)

    if(0 == strcmp(fio, _persons[i].GetFio()))

    return _persons+i;

    return 0;//ничего не найдено

    }
    //искать по возрасту

    Person* Group::FindPerson(double age)

    {

    for(unsigned i = 0; i < _size; ++i)

    if(age == _persons[i].GetAge())

    return _persons+i;

    return 0;//ничего не найдено

    }
    //оператор вывода в поток

    ostream& operator <<(ostream& os, Group const& g)

    {

    for(unsigned i = 0; i < g.Size(); ++i)

    os << "Person #" << i << ":\n"<< g.GetPerson(i);

    os << (g.Size() ? "" : "empty") << endl;

    return os;

    }

    Заключение
    Видим что программа отработала хорошо и все данные вывела на экран .


    написать администратору сайта