Создание многофайлового проекта

Один из наиболее фундаментальных принципов разработки хорошего программного обеспечения состоит в отделении интерфейса от реализации. Это облегчает модификацию программ. Что касается клиентов класса, то изменения в реализации класса не влияют на клиента до тех пор, пока интерфейс класса, изначально предназначенный для клиента, остается неизменным.

При построении программы на С++ каждое определение класса обычно помещается в заголовочный файл. Чтобы оно было доступно любому клиенту, который захочет использовать класс. Это формирует открытый интерфейс класса.

Определения функций-элементов этого класса помещаются в файлы исходных кодов с теми же базовыми именами. Это формирует реализацию класса.

Заголовочные файлы включаются (посредством #include) в каждый файл, в котором используется класс, а файлы с исходными кодами компилируются и компонуются с файлом, содержащим главную программу. Нужно для используемого компилятора посмотреть документацию, чтобы определить, как компилировать и компоновать программы, содержащие множество исходных файлов.

Разобьем рассмотренную выше программу на ряд файлов. Программа будет состоять из заголовочного файла student.h, в котором объявляется класс student, файла student.cpp, в котором описываются функции-элементы класса student, и файла client.cpp, в котором описывается функция main, в которой.

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

//Предотвращение многократного включения

//заголовочного файла

#ifndef STUDENT_H

#define STUDENT_H

/*определение класса student*/

#endif

Приведенные выше директивы препроцессора предотвращают включение кода между #ifndef и #endif, если определено имя STUDENT_H. Если заголовок еще не включался в файл, то имя STUDENT_H определяется директивой #define и операторы заголовочного файла включаются в результирующий файл. Если же заголовок уже был включен ранее, STUDENT_H уже определен и операторы заголовочного файла повторно не включаются. Попытки многократного включения заголовочного файла обычно случаются в больших программах с множеством заголовочных файлов, которые могут сами включать другие заголовочные файлы.

Отметим, что в интегрированной среде разработки Visual C++ вместо указанных выше директив для предотвращения многократного включения заголовочного файла можно использовать директиву

#pragma once

перед определением класса student.

При построении больших программ в заголовочные файлы будут помещаться также и другие определения и объявления.

По негласному соглашению в приведенных выше директивах используется имя символической константы, представляющее собой просто имя заголовочного файла с символом подчеркивания вместо точки.

Файл student.h:

//Листинг 14.2

//#pragma once - директива для Visual C++

#ifndef STUDENT_H

#define STUDENT_H

class student {

private:

char *name; //фамилия студента

int number; //номер зачетной книжки

 

public:

student(); //конструктор с умолчанием

student(char*,int);//конструктор с параметрами

//конструктор копирования

student(const student& ob);

student(int); //конструктор преобразования

student(char*); //конструктор преобразования

~student(void); //деструктор

 

//функции-элементы изменения закрытых данных

void setname(char*);//изменяет фамилию студента

void setnumber(int); //изменяет номер зачетки

 

//функции-элементы чтения закрытых данных возвращает фамилию студента

const char* getname(void);

int getnumber(void);//возвращает номер зачетки

};

#endif

 

Файл student.cpp:

//Листинг 14.3

//Определение функций-элементов класса student

#include "student.h"

#include<cstring>

#include<iostream>

using namespace std;

//конструктор с умолчанием (без параметров)

student::student()

{name=0;

number=0;

cout<<"constructor without parameters\n";}

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

student::student(char* fam,int num)

{ name=new char[strlen(fam)+1];

strcpy(name,fam);

number=num;

cout<<"constructor for "<<name<<endl;}

//конструктор копирования

student::student(const student& ob)

{ number=ob.number;

name=new char[strlen(ob.name)+1];

strcpy(name,ob.name);

cout<<"constructor copy "<<name<<endl; }

 

//конструктор преобразования

student::student(int num)

{

//используем значение поля name по умолчанию

name=0;

number=num;

cout<<"constructor preobrazovania"<<number<<endl;

}

 

//конструктор преобразования

student::student(char* fam)

{ name=new char[strlen(fam)+1];

strcpy(name,fam);

//используем значение поля number по умолчанию

number=555;

cout<<"constructor preobrazovania "<<name<<endl;

}

 

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

student::~student(void)

{ cout<<"destructor "<<name<<endl;

delete [] name; }

//функции-элементы изменения закрытых данных

void student::setname(char *fam)

{ delete [] name;

name=new char[strlen(fam)+1];

strcpy(name,fam);}

void student::setnumber(int n)

{ number=n;}

//функции-элементы чтения закрытых данных

const char* student::getname(void)

{return name;}

int student::getnumber(void)

{return number; }

 

Файл client.cpp:

//Листинг 14.4

//проверка класса student

#include"student.h"

#include<iostream>

using namespace std;

int main()

{ int n,nm;

char temp[20];

//определение объекта класса

student stud1("Petrov",563);

//определена ссылка на объект

student &st=stud1;

//вызывается конструктор копирования

student stud2(stud1);

cout<<stud1.getname()<<"\t"<<st.getnumber()<<endl;

cout<<stud2.getname()<<"\t"<<stud2.getnumber()<<endl;

//вызывается конструктор преобразования

student stud3(12345);

 

//создается временный неименованный объект

//для этого объекта вызывается конструктор //преобразования

student stud4="Ivanov";

cout<<stud4.getname()<<"\t"<<stud4.getnumber()<<endl;

 

cin>>n;

//создается динамический массив объектов

student *spisok= new student[n];

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

{ cin>>temp>>nm;

spisok[i].setnumber(nm);

spisok[i].setname(temp);

cout<<spisok[i].getname()<<"\t"<<spisok[i].getnumber()<<endl;

}

//удаляется динамический массив

delete [] spisok;

return 0;

}


Задание:

Создать класс согласно своему варианту. Класс должен содержать конструктор с умолчанием, конструктор с параметрами, методы чтения и изменения закрытых данных.

Можно добавить другие методы.

Написать программу, тестирующую все методы класса. Создать многофайловый проект.

Вариант 1

Класс PPoint для работы с точками на плоскости, заданными в полярных координатах. Обязательно должны быть реализованы: перемещение точки по оси X, перемещение по оси Y, определение расстояния между двумя точками, преобразование в декартовы координаты, сравнение на совпадение и несовпадение.

 

Вариант 2

Описать класс прямоугольников со сторонами, параллельными осям координат. Предусмотреть возмож­ность перемещения прямоугольников на плоскости, измене­ние размеров, построение наименьшего прямоугольника, содержащего два заданных прямоугольника, и прямоуголь­ника, являющегося общей частью (пересечением) двух прямоугольников.

 

Вариант 3

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

 

Вариант 4

Описать класс «домашняя библиотека». Предусмот­реть возможность работы с произвольным числом книг, поиска книги по какому-либо признаку (например, по автору или по году издания), добавления книг в библиотеку, удаления книг из нее, сортировки книг по разным полям.

 

Вариант 5

Класс Cylinder для представления цилиндра. Поля данных должны включать координаты центра и радиус основания, высоту цилиндра. Требуется реализовать опера­ции: вычисление площади основания, вычисление длины описывающей основание окружности, вычисление площади боковой поверхности цилиндра, вычисление объема фигуры, а также сравнение разных цилиндров по объему.

 

Вариант 6

Класс Detail (деталь), содержащий поля: наименова­ние детали, артикул (целое число), коэффициент сложности изготовления, наименование металла, из которого произво­дится деталь, цена единицы веса металла, вес детали. Реали­зовать методы изменения сложности изготовления детали, наименования металла, цены единицы веса металла, веса детали, вычисления стоимости детали на основании цены единицы веса металла, веса детали и коэффициента слож­ности изготовления детали, а также сравнение деталей на совпадение и несовпадение по наименованию и артикулу.

 

Вариант 7

Класс Angle для работы с углами на плоскости, задаваемыми величиной в градусах и минутах. Обязательно должны быть реализованы: перевод в радианы, приведение к диапазону 0–360, увеличение и уменьшение угла на заданную величину, получение синуса, сравнение углов.

 

Вариант 8

Класс Ring, представляющий собой разовый платеж за телефонный разговор. Класс должен содержать поля: номер телефона, тариф оплаты минуты разговора, скидка (в процентах), время начала разговора (в часах и минутах), продолжительность разговора (в минутах) и сумма к оплате. Релизовать метод вычисления суммы к оплате, а также ме­тод, определяющий «аналогичность» платежей (по одина­ковому номеру телефона). Скидка формируется в зависи­мости от времени начала разговора (ночью скидка больше).

 

Вариант 9

Класс Rusmoney предназначен для работы с денежны­ми суммами. Сумма должна быть представлена полями-номиналами, значениями которых должно быть количество купюр данного достоинства. Номиналы российских рублей могут принимать значения 1, 2, 5, 10, 50, 100, 500, 1000, 5000. Копейки представить как 0.01 (1 копейка), 0.05 (5 копеек), 0.1 (10 копеек), 0.5 (50 копеек). Реализовать сложение сумм, вычитание сумм, деление сумм, деление суммы на дробное число, умножение на дробное число и операции сравнения. Дробная часть (копейки) при выводе на экран должна быть отделена от целой части запятой.

 

Вариант 10

Класс Payment (зарплата). В классе должны быть представлены поля: фамилия-имя-отчество, оклад, год поступления на работу, процент надбавки, подоходный налог, количество отработанных дней в месяце, количество рабочих дней в месяце, начисленная и удержанная суммы. Реализовать методы вычисления начисленной суммы, вычисления удержанной суммы, вычисления суммы, выдаваемой на руки, вычисления стажа. Стаж вычисляется как полное количество лет, прошедших от года поступления на работу, до текущего года. Начисления представляют собой сумму, начисленную за отработанные дни, и надбавки, то есть доли от первой суммы. Удержания представляют собой отчисления в пенсионный фонд (1% от начисленной суммы) и подоходный налог (13% от начисленной суммы без отчислений в пенсионный фонд).

 

Вариант 11

Класс Time для работы со временем. Время представляется тремя полями: часами, минутами и секундами. Обязательными операциями являются: вычисление разницы между двумя моментами времени в секундах, сложение времени и заданного количества секунд, вычитание из времени заданного количества секунд, сравнение моментов времени, перевод в секунды, перевод в минуты (с округлением до целой минуты).

 

Вариант 12

Класс Account, представляющий собой банковский счет. В классе должны быть четыре поля: фамилия владельца, номер счета, процент начисления и сумма в рублях. Необходимо выполнять следующие операции: сменить владельца, снять некоторую сумму денег со счета, положить деньги на счет, начислить проценты, перевести сумму в доллары, перевести сумму в евро, получить сумму прописью (преобразовать в числительное).

 

Вариант 13

Класс Googs (товар на складе), содержащий поля: наименование товара, дата оформления, цена, количество единиц товара, номер накладной, по которой товар поступил на склад. Реализовать методы изменения цены товара, изменения количества товара, вычисления общей стоимости товара, хранящегося на складе.

 


Вариант 14

Класс Date для работы с датами. Дата представляется тремя полями: годом, месяцем и днем. Обязательными операциями являются: вычисление даты через заданное количество дней, вычитание заданного количества дней из даты, определение високосного года, присвоение и получение отдельных частей (год, месяц, день), сравнение дат (равно, до, после), вычисление количества дней между датами. (Указание: каждый год, число которого делится на 4, является високосным кроме годов, числа которых оканчиваются на 2 нуля, но не делятся на 400. Например, 1700 и 1800 годы не являются високосными.)

 

Вариант 15

Класс Point для работы с точками на плоскости. Координаты точки – декартовы. Обязательно должны быть реализованы: перемещение точки по оси X, перемещение по оси Y, определение расстояния до начала координат, рас­стояния между двумя точками, преобразование в полярные координаты, сравнение на совпадение и несовпадение.

 

Вариант 16

Класс Money для работы с денежными суммами. Чис­ло должно быть представлено двумя полями: рубли и ко­пейки. Дробная часть (копейки) при выводе на экран дол­жна быть отделена от целой запятой. Реализовать сложение, вычитание, деление сумм, деление суммы на дробное число, умножение на дробное число и операции сравнения.

 

Вариант 17

Класс Triangle для представления треугольника. Поля данных должны включать углы и стороны. Требуется реализовать операции: вычисление площади, вычисление периметра, вычисления высот, а также определения вида треугольника (равносторонний, равнобедренный или прямоугольный).

 

Вариант 18

Класс Bankomat, моделирующий работу банкомата. В классе должны содержаться поля для хранения идентифи­кационного номера банкомата, информацию о текущей сумме денег, оставшейся в банкомате, минимальной и максимальной суммах, которые позволяется снять клиенту в один день. Сумма денег представляется полями-номиналами 10–5000. Реализовать метод инициализации банкомата, метод загрузки купюр в банкомат и метод снятия определенной суммы денег. Метод снятия денег должен выполнять проверку на корректность снимаемой суммы: она не должна быть меньше минимального значения и не должна превышать максимальное значение.

 

Вариант 19

Класс vector3D, задаваемый тремя координатами. Обязательно должны быть реализованы: сложение и вычитание векторов, скалярное произведение векторов, умножение на скаляр, сравнение векторов, вычисление длины вектора, сравнение длин векторов.

Вариант 20

Класс ModelWindow для работы с моделями экранных окон. В качестве полей задаются: заголовок окна, координаты левого верхнего угла, размер по горизонтали, размер по вертикали, цвет окна, состояние "видимое/невидимое", состояние "с рамкой/без рамки". Координаты и размеры указываются в целых числах. Реализовать операции: передвижение окна по горизонтали, по вертикали, изменение высоты и/или ширины окна, изменение цвета, изменение состояния, опрос состояния. Операции передвижения и изменения размера должны осуществлять проверку на пересечение границ экрана.


Практическое занятие 15. Создание многофайлового проекта с использованием компилятора g++

 

Создание многофайлового проекта с использованием компилятора g++ рассмотрим на примере программы, состоящей из трех файлов: заголовочного файла student.h (листинг 14.2), в котором объявляется класс student, файла student.cpp (листинг 14.3), в котором описываются функции-элементы класса student, и файла client.cpp (листинг 14.4), в котором описывается функция main.

 

Преобразование нескольких исходных файлов в готовую к запуску программу с использованием компилятора g++

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

$ g++ proverka.cpp student.cpp -o myappl

 

Для компиляции исходного кода с подавлением компоновки и, соответственно, вывода объектного файла вместо исполняемого применяется опции –c. Например, по следующей команде исходный файл client.cpp будет скомпилирован в объектный файл client.o:

$ g++ -c client.cpp

Программа g++ также распознает файлы с суффиксом. o в качестве входных и передает их компоновщику (linker):

$ g++ -c client.cpp

$ g++ -c student.cpp

$ g++ client.o student.o -o myappl

здесь опция -o используется для присвоения имени исполняемому файлу.

 

Но собирать программы таким простым способом можно только в учебных целях. В профессиональной же работе ваши проекты будут включать большое количество файлов, и вам придётся пользоваться утилитой make.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: