Главная страница

Лабораторная_работа_n1_shodibek_norkulov. Лабораторная работа 1 Студент Норкулов Шодибек Группа 94320 классы и объекты в с


Скачать 470.95 Kb.
НазваниеЛабораторная работа 1 Студент Норкулов Шодибек Группа 94320 классы и объекты в с
Дата15.06.2021
Размер470.95 Kb.
Формат файлаdocx
Имя файлаЛабораторная_работа_n1_shodibek_norkulov.docx
ТипЛабораторная работа
#217677

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

Студент: Норкулов Шодибек

Группа: 943-20

КЛАССЫ И ОБЪЕКТЫ В С++
Цель. Получить практические навыки реализации классов на С++.
Основное содержание работы.

Написать программу, в которой создаются и разрушаются объекты, определенного пользователем класса. Выполнить исследование вызовов конструкторов и деструкторов.

Краткие теоретические сведения.

Класс.


Класс  фундаментальное понятие С++, он лежит в основе многих свойств С++. Класс предоставляет механизм для создания объектов. В классе отражены важнейшие концепции объектно-ориентированного программирования: инкапсуляция, наследование, полиморфизм.

С точки зрения синтаксиса, класс в С++  это структурированный тип, образованный на основе уже существующих типов.

В этом смысле класс является расширением понятия структуры. В простейшем случае класс можно определить с помощью конструкции:

тип_класса имя_класса{список_членов_класса};

где

тип_класса – одно из служебных слов class, struct, union;

имя_класса – идентификатор;

список_членов_класса – определения и описания типизированных данных и принадлежащих классу функций.

Функции – это методы класса, определяющие операции над объектом.

Данные – это поля объекта, образующие его структуру. Значения полей определяет состояние объекта.
Примеры.

struct date // дата

{int month,day,year; // поля: месяц, день, год

void set(int,int,int); // метод – установить дату

void get(int*,int*,int*); // метод – получить дату

void next(); // метод – установить следующую дату

void print(); // метод – вывести дату

};

struct class complex // комплексное число

{double re,im;

double real(){return(re);}

double imag(){return(im);}

void set(double x,double y){re = x; im = y;}

void print(){cout<<“re = “<
};

Для описания объекта класса (экземпляра класса) используется конструкция

имя_класса имя_объекта;

date today,my_birthday;

date *point = &today; // указатель на объект типа date

date clim[30]; // массив объектов

date &name = my_birthday; // ссылка на объект

В определяемые объекты входят данные, соответствующие членам  данным класса. Функции  члены класса позволяют обрабатывать данные конкретных объектов класса. Обращаться к данным объекта и вызывать функции для объекта можно двумя способами. Первый с помощью “квалифицированных” имен:

имя_объекта. имя_данного

имя_объекта. имя_функции
Например:

complex x1,x2;

x1.re = 1.24;

x1.im = 2.3;

x2.set(5.1,1.7);

x1.print();
Второй способ доступа использует указатель на объект

указатель_на_объект–>имя_компонента
complex *point = &x1; // или point = new complex;

point –>re = 1.24;

point –>im = 2.3;

point –>print();
Доступность компонентов класса.

В рассмотренных ранее примерах классов компоненты классов являются общедоступными. В любом месте программы, где “видно” опреде-
ление класса, можно получить доступ к компонентам объекта класса. Тем самым не выполняется основной принцип абстракции данных – инкапсуляция (сокрытие) данных внутри объекта. Для изменения видимости компонент в определении класса можно использовать спецификаторы доступа: public, private, protected.

Общедоступные (public) компоненты доступны в любой части программы. Они могут использоваться любой функцией как внутри данного класса, так и вне его. Доступ извне осуществляется через имя объекта:

имя_объекта.имя_члена_класса

ссылка_на_объект.имя_члена_класса

указатель_на_объект->имя_члена_класса
Собственные (private) компоненты локализованы в классе и не доступны извне. Они могут использоваться функциями – членами данного класса и функциями – “друзьями” того класса, в котором они описаны.

Защищенные (protected) компоненты доступны внутри класса и в производных классах.
Изменить статус доступа к компонентам класса можно и с помощью использования в определении класса ключевого слова class. В этом случае все компоненты класса по умолчанию являются собственными.

Пример.

class complex

{

double re, im; // private по умолчанию

public:

double real(){return re;}

double imag(){return im;}

void set(double x,double y){re = x; im = y;} };

Заданий № 14
14. АВТОМОБИЛЬ

марка – string

мощность – int

стоимось – float
Код

#include

#include
using namespace std;
class Cars {

private:

string model;

int power;

float price;
public:

void Car (string m_model, int m_power, float m_price) {

model = m_model; power = m_power; price = m_price;

}
void print() {

cout << "Марка: " << model << " Мощность: " << power << " Стоимось: " << price <<"$" << endl;

}
};
int main() {

setlocale(LC_ALL, "Russian");

int n;

cin>>n;

Cars CarW[n];

string amodel;

int apower;

float aprice;

for(int i = 0; i < n; i++){

cin >> amodel >> apower >> aprice;

CarW[i].Car(amodel, apower, aprice);
}

for(int i = 0; i < n; i++){

CarW[i].print();

}

return 0;

}



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

Студент: Норкулов Шодибек

Группа: 943-20
Программирование с использованием
наследования классов


Язык С++ позволяет классу наследовать данные-элементы и функции-элементы одного или нескольких других классов. Новый класс называют производным классом. Класс, элементы которого наследуются производным классом, называется базовым классом. В свою очередь производный класс может служить базовым для другого класса. Наследование дает возможность заключить некоторое общее или схожее поведение различных объектов в одном базовом классе.

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

Общий вид наследования:

class Base

{

// …..

};

class Derived: <ключ доступа> Base

{

// ……………

};

Ключ доступа может быть private, protected, public. Если ключ не указан, то по умолчанию он принимается private.

Наследование позволяет рассматривать целые иерархии классов и работать со всеми элементами одинаково, приводя их к базовому. Правила приведения следующие:

Ошибки приведения базового класса к наследуемому отслеживаются программистом.

Доступ к элементам класса

При наследовании ключ доступа определяет уровень доступа к элементам базового класса внутри производного класса. В таблице 15.1 описаны возможные варианты доступа.

Таблица 15.1

Наследование

Доступ в
базовом классе

Доступ в производном классе

public

public

protected

private

public

protected

private


protected

public

protected

private

protected

protected

private


private

public

protected

private

private

private

private

Конструкторы и деструкторы при наследовании

Конструкторы не наследуются. Если конструктор базового класса требует спецификации одного или нескольких параметров, конструктор производного класса должен вызывать базовый конструктор, используя список инициализации элементов.

Пример 15.1.

#include

class Base

{ public:

Base(int, float);

};

class Derived: Base

{ public:

Derived(char* lst, float amt);

};

Derived:: Derived(char* lst, float amt) : Base(strlen(lst),amt)

{ }

В деструкторе производного класса компилятор автоматически генерирует вызовы базовых деструкторов, поэтому для удаления объекта производного класса следует сделать деструктор в базовых классах виртуальным. Для вызова используется delete this либо operator delete.

Виртуальные функции

Функция-элемент может быть объявлена как virtual. Ключевое слово virtual предписывает компилятору генерировать некоторую дополнительную информацию о функции. Если функция переопределяется в производном классе и вызывается с указателем (или ссылкой) базового класса, ссылающимся на представитель производного класса, эта информация позволяет определить, какой из вариантов функции должен быть выбран: такой вызов будет адресован функции производного класса.

Для виртуальных функций существуют следующие правила:

  • виртуальную функцию нельзя объявлять как static.

  • спецификатор virtual необязателен при переопределении функции в производном классе.

  • виртуальная функция должна быть определена в базовом классе и может быть переопределена в производном.

Заданий № 1

Разработать программу с использованием наследования классов, реализующую классы:

-графический объект;
-круг;
-квадрат.

Используя виртуальные функции, не зная с объектом какого класса вы работаете, выведите на экран его характеристики.

КОД

#include

using namespace std;

class Figure {

protected:

string name;

string color;

};

class Circle: public Figure {

public:

double p = 3.14;

int a;

void SetFigure (string name, string color,int a) {

this -> name = name;

this -> color = color;

this -> a = a;

}

void GetFigure() {

cout << "Фигура: " << name << endl << "Цвет: " << color << endl <<"Поверхность: " << p*(a*a) << endl << "\n";

}

};

class Square: Figure {

public:

int b;

void SetFigure (string name,string color,int b) {

this -> name = name;

this -> color = color;

this -> b = b;

}

void GetFigure () {

cout << "Фигура: " << name << endl << "Цвет: " << color << endl <<"Поверхность: " << b * b << endl;

}

};

int main() {

setlocale(LC_ALL, "Russian");

Circle c;

Square s;

c.SetFigure("Круг","Чернить", 5);

c.GetFigure();

s.SetFigure("Квадрат","Красный",10);

c.GetFigure();

}





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

Студент: Норкулов Шодибек

Группа: 943-20

Линейные контейнеры (массив, вектор, deque, list, forward_list)

Контейнер — это специализированный класс, предназначенный для хранения массива однотипных объектов и обеспечения доступа к этим объектам. Кроме array, остальные контейнеры (в том числе и string) содержат массивы, являющиеся динамическими. Из этого следует, что контейнеры могут управлять выделяемой памятью, т. е. изменять свой размер. Для различных контейнеров имеются как общие, так и специфичные методы, применимые только для определенного контейнера. Забегая немного вперед, заметим, что отдельные контейнеры имеет свои методы, которые необходимо применять вместо обобщенных алгоритмов (например, поиска для ассоциативных контейнеров). Согласно стандарту C++, любой контейнер должен содержать методы begin(), end(), size(), max_size(), empty() и swap(). Общие методы для контейнеров могут иметь разную эффективность. Доступ к элементам в контейнерах предоставляется с помощью функций-членов (vector, deque) или только через итераторы (list, set). Контейнеры, в которых элементы располагаются последовательно, один за другим, называются последовательными контейнерами. Последовательные контейнеры реализуют классы:

array

vector

deque

list

vecДля работы с размером и объемом вектора определены следующие методы:

empty() Возвращает true, если вектор пуст

size() Возвращает количество элементов в векторе

max_size() Возвращает максимально возможное количество элементов в векторе

reserve() Устанавливает минимально возможное количество элементов в векторе

capacity() Возвращает количество элементов, которое может содержать вектор до того, как ему потребуется выделить больше места.

shrink_to_fit() Уменьшает количество используемой памяти за счет освобождения неиспользованной

Модификаторы и функция-член assign()

Для вектора определены следующие модификаторы:

clear() Очищает контейнер

insert() Вставляет элементы

emplace() Создает элементы на месте (в позиции итератора). Не используется копирование или перемещение. В определенных задачах может использоваться вместо insert()

emplace_back() Создает элементы на месте в конце массива

erase() Удаляет элементы

push_back() Добавляет элемент в конец

pop_back() Удаляет последний элемент

resize() Изменяет количество хранимых элементов

swap() Обменивает содержимое

assign() Заменяет содержимое вектора на новое

Присваивание заменяет значение одного вектора значением другого. Это фактически, равносильно применению метода assign()

Заданий № 2

Дано целое число N (> 0). Сформировать и вывести целочисленный массив размера N, содержащий N первых положительных нечетных чисел: 1, 3, 5,

#include

#include

using namespace std;

int main() {

int n,a = 1;

cin >> n;

vector myVector;

for(int i = 1; i <= n; i++) {

if(i%2 !=0 ) {

myVector.push_back(i);

}

}

for(auto it = myVector.begin(); it != myVector.end(); it++) {

cout << *it << " ";

} }





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