Задачи и порядок выполнения работы В работе необходимо разобраться с понятием класса некоторой предметной области и соответствующему ему класса как типа языка Си++, введенного пользователем. Также необходимо знать отличие классов от объектов и назначение и порядок использования основных элементов класса в Си++: полей, методов (функций класса), конструкторов, деструктора. Обратить внимание на способы создания массива объектов класса динамически.
Студент разрабатывает программу на языке Си++ в виде консольного приложения, в программе необходимо создать массив объектов некоторого класса, число элементов массива заранее неизвестно и вводится с клавиатуры. Параметры каждого объекта также вводятся с клавиатуры. Для небольшого числа объектов студент выполняет ручной расчет для проверки работы программы. Результаты работы программы и результаты ручного расчета представляет преподавателю в отчете.
Условие задачи:
Класс автомобиль. Содержит поля (статус доступа private):
- название (марка);
- средний расход топлива (в литрах на 100 км).
Методы и конструкторы:
- конструктор для инициализации полей;
- метод для расчета требуемого объема топлива для заданного пробега (метод имеет 1 параметр, который задает требуемый пробег в километрах, возвращает требуемый объем топлива в литрах);
- метод для печати параметров объекта.
При необходимости можно использовать другие методы и конструкторы.
Требуется: создать массив объектов класса, рассчитать требуемый суммарный объем топлива для заданного пробега всех автомобилей, пробег вводится с клавиатуры, вывести на печать параметры объектов и рассчитанный объем топлива.
Пример выполнения работы
Следует отметить, что для создания массива объектов динамически, когда существует конструктор с параметрами для инициализации полей объекта, можно использовать два основных способа.
Особенности первого способа:
- необходимо в класс включить конструктор без параметров и отдельный метод для инициализации полей, например, с именем set и числом параметров, которые соответствуют числу инициализируемых полей класса;
- объявляем указатель на массив объектов, если имя класса MyClass, то это объявление может иметь вид: MyClass *pOb;
- задаем число объектов, например, вводим с клавиатуры как значение целой переменой n, и создаем массив объектов динамически pOb=new MyClass[n]; здесь, при создании каждого объекта, вызывается конструктор без параметров, именно для этого его и нужно включить в класс;
- в цикле для каждого объекта вводим параметры для его инициализации и инициализируем уже созданный объект с помощью вызова метода set, это действие может иметь вид pOb[i].set(…); где в метод set вместо многоточия передаются фактические параметры.
Особенности второго способа (здесь не нужен конструктор без параметров и метод set):
- объявляем указатель на указатель на массив объектов, если имя класса MyClass, то это объявление может иметь вид: MyClass **ppOb;
- задаем число объектов, например, вводим с клавиатуры как значение целой переменой n, и создаем массив указателей динамически ppOb=new MyClass*[n];
- в цикле для каждого объекта вводим параметры для его инициализации и создаем объект динамически с помощью вызова конструктора с параметрами, это действие может иметь вид ppOb[i]=new MyClass(…); где вместо многоточия передаются фактические параметры для конструктора класса.
Ниже в листинге показаны оба способа, один из способов представлен в виде комментариев. Для решения задачи в среде Microsoft Visual Studio 2013 было создано стандартное консольное приложение (проект типа Win32 Console Application, в русифицированной версии Консольное приложение Win32). Исходные коды основного файла проекта (файла с расширением .cpp) и файла stdafx.h приведены ниже.
Листинг программы с комментариями:
// Основной файл проекта
#include "stdafx.h"
using namespace std;// В этом пространстве имен находятся объекты cin и cout
// cin - стандартный объект ввода, cout - стандартный объект вывода
class Avt // Класс автомобиль
{
char marka[64]; // Марка
double rash; // Расход топлива на 100 км
public:
Avt() // Конструктор без параметров создает "пустой" объект
{
rash = marka[0] = 0;
}
void set(char mar[], double r) // Функция для инициализации полей для
// созданного "пустого" объекта
{
strcpy_s(marka, mar); // Копируем строку, содержащую марку автомобиля
rash = r; // Задаем значение расхода топлива на 100 км
}
Avt(char mar[], double r) // Конструктор для инициализации полей
{
strcpy_s(marka, mar); // Копируем строку, содержащую марку автомобиля
rash = r; // Задаем значение расхода топлива на 100 км
}
double getRash(double dlina)// Функция возвращает - сколько нужно топлива для
// пробега заданного расстояния
{
return rash*dlina / 100.;
}
void print() // Функция для печати полей объекта
{
cout << "\nmarka: " << marka << " rashod na 100 km=" << rash;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
int n; // Неизвестное число объектов
cout << "n="; cin >> n; // Ввод с клавиатуры n
double rast; // Расстояние, для которого требуется вычислить расход топлива
cout << "rast="; cin >> rast; // Ввод с клавиатуры расстояния
double SumRashod = 0; // Суммарный расход топлива для всех автомобилей
char S[64]; double r; // Вспомогательные переменные для ввода марки
// автомобиля и расхода топлива
/************************************************************************
Первый способ создаем массив "пустых" объектов и инициализируем их с
помощью функции set
***********************************************************************/
/*
Avt *pAvt; // Указатель на массив
pAvt=new Avt[n]; // Для каждого объекта вызывается конструктор без параметров,
// т.е. созданы "пустые" объекты
// Цикл ввода данных для объектов
for(int i=0; i<n; i++)
{
cout<<"Object N="<<(i+1)<<":\n"<<"marka: ";
cin>>S; // Ввод марки автомобиля
cout<<"Rashod="; cin>>r; // Ввод расхода топлива
pAvt[i].set(S, r); // Вызываем функцию set для инициализации полей
// объектов
}
// Цикл печати полей для объектов
for(int i=0; i<n; i++) pAvt[i].print();
// Цикл для расчета суммарного расхода топлива
for(int i=0; i<n; i++) SumRashod+=pAvt[i].getRash(rast);
*/
/**************************************************************************
Конец первого способа
***********************************************************************/
/************************************************************************
Второй способ создаем массив указателей на объекты и
далее каждый объект создается динамически с помощью конструктора с инициализацией
***********************************************************************/
Avt **ppA; // Указатель на массив указателей
ppA = new Avt*[n]; // Создаем массив указателей
for (int i = 0; i<n; i++)
{
cout << "Object N=" << (i + 1) << ":\n" << "marka: ";
cin >> S; // Ввод марки автомобиля
cout << "Rashod="; cin >> r; // Ввод расхода топлива
ppA[i] = new Avt(S, r); // Создание объекта динамически
// с вызовом конструктора с параметрами
}
// Цикл печати полей для объектов
for (int i = 0; i<n; i++) ppA[i]->print();
// Цикл для расчета суммарного расхода топлива
for (int i = 0; i<n; i++) SumRashod += ppA[i]->getRash(rast);
/**************************************************************************
Конец второго способа
************************************************************************/
cout << "\nSumRashor=" << SumRashod; // Вывод на печать суммарного расхода топлива
system("pause"); // Останавливаем программу до нажатия любой клавиши
return 0;
}
// Файл stdafx.h
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <tchar.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
|