Консультация № 175493
21.12.2009, 18:07
35.00 руб.
0 13 1
Уважаемые эксперты, помогите пожалуйста разобраться.
У меня такая задача
Создать абстрактный класс CVerhicle. На его основе реализовать классы CPlane, CCar и CShip. Классы должны иметь возможность задавать и получать координаты, параметры средств передвижения (цена, скорость, год выпуска). Для самолета должна быть определена высота, для самолета и корабля - количество пассажиров. Для корабля - порт приписки. Написать программу, создающую список объектов этих классов в динамической памяти. Программа должна содержать меню.
Код к ней в приложении.
Объясните пожалуйста методы которые описаны в виртуальном классе, и зачем там нужна структура из двух полей, не понятна основная программа. Я оставил комментарии в самой задачи где мне не ясно.


Приложение:
#include <string>
#include <list>
#include <iostream>
#include <conio>

using namespace std;
struct CPoint //зачем нужна структура?
{
int x;
int y;
};


class CVehicle
{

public:
virtual void move()=0;
CPoint GetCoords() {return coord;}
int GetPrice() {return price;} //насколько я понял это метод ввода
void SetPrice(int price) {this->price=price;} //а это метод вывода, объясните плииз что значит this->price=price; опишите пожалуйста вывод полей к примеру в классе CShip
int GetVelocity() {return velocity;}
void SetVelocity(int velocity) {this->velocity=velocity;}
int GetYear() {return prodYear;}
void SetYear(int prodYear) {this->prodYear=prodYear;}
CVehicle ()
{
this->coord.x=0;
this->coord.y=0;
this->price=0;
this->velocity=0;
this->prodYear=0;
}

CVehicle (CPoint coord, int price, int velocity, int prodYear)
{
this->coord=coord;
this->price=price;
this->velocity=velocity;
this->prodYear=prodYear;
};
void SetCoords(CPoint coord) {this->coord=coord;}
protected:
CPoint coord;
int price;
int velocity;
int prodYear;
};

class CCar: public CVehicle
{
public:
CCar()
{
};
CCar(CPoint coord, int price, int velocity, int prodYear, int passengers):CVehicle(coord, price, velocity, prodYear)
{
};
void move()
{
cout<<"The car moves"<<endl;
}
};
class CShip: public CVehicle
{
public:
CShip()
{
this->passengers=0;
this->port="";
};

CShip(CPoint coord, int price, int velocity, int prodYear, int passengers,string port):CVehicle(coord, price, velocity, prodYear)
{
this->passengers=passengers;
this->port=port;
};
int GetPassengers() {return passengers;}
void SetPassengers(int passengers) {this->passengers=passengers;}
string GetPort() {return port;}
void SetPort(string port) {this->port=port;}
void move()
{
cin>>passengers;
cout<<"Ship passengers"<<passengers;
cout<<"The ship moves"<<endl;
}
private:
int passengers;
string port;

};

class CPlane:public CVehicle
{
private:
int passengers;
int height;
public:

CPlane()
{
this->passengers=0;
this->height=0;
};
CPlane(CPoint coord, int price, int velocity, int prodYear, int passengers,int height):CVehicle(coord, price, velocity, prodYear)
{
this->passengers=passengers;
this->height=height;
};
int GetPassengers() {return passengers;}
void SetPassengers(int passengers) {this->passengers=passengers;}
int GetHeight() {return height;}
void SetHeight(int height) {this->height=height;}
void move()
{
cin>>passengers;
cout<<"Plane passengers"<<passengers;
cout<<"The plane moves"<<endl;
}

};

void main()
{
CVehicle *mashinka=new CCar();
CVehicle *samoletik=new CPlane();
CVehicle *korablik=new CShip();
list<CVehicle*> zhelezki;
list<CVehicle*>::iterator it; //что здесь объявляется?
zhelezki.push_back(mashinka);
zhelezki.push_back(samoletik);//как я понял здесь уже вызывается объект со своими методами
zhelezki.push_back(korablik);
for(it=zhelezki.begin();it!=zhelezki.end();it++) //тоже не понятно
(*it)->move(); //не понятно
getch();
}

Обсуждение

Неизвестный
21.12.2009, 20:49
общий
Нужен только ввод, изменение данных и вывод, одного любого класса
давно
Профессор
230118
3054
21.12.2009, 22:55
общий
это ответ
Здравствуйте, S K A L T .

1. Структура CPoint нужна, чтобы описывать координаты. Они состоят из 2 чисел - широты и долготы, то есть одного числа было бы недостаточно.
2. Инкапсуляция - один из принципов объектно-ориентированного программирования. Его суть в том, что данные, которые хранятся в классе, должны быть заключены в нем как в шкатулке. Для того, чтобы узнать значения данных или изменить их, применяют методы get/set. Например, int GetPrice() - это методы вывода, позволяет узнать внешней программе о значении цены. SetPrice - метод установки цены. В методах класса существует специальный указатель this. Это указатель на член класса. Если класс определяет данные, которые у каждого экземпляра объекта будут индивидуальны, this->priceпозволяет обращаться к цене объекта, а price - это аргумент функции. Функция устанавливает внутреннее значение цены равным аргументу функции.

list<CVehicle*> zhelezki; здесь создается список объектов. Наверное, можно было бы обойтись простым массивом. list - это и есть список. list<CVehicle*>::iterator it; - это итератор - объект, который позволяет путешествовать по списку. Его аналогом для массива был бы индекс i.
Если для перебора массива инкрементируется i, для листа инкрементируется итератор.
for(it=zhelezki.begin();it!=zhelezki.end();it++) это аналог for(i=0;i!=т;i++) , который обычно применяется при переборе массива.
zhelezki.push_back(samoletik); - в список заталкивается очередной объект.
Обратите внимание на <CVehicle*>. Это лист указателей на CVehicle. Если бы это был список CVehicle, невозможно было бы создать его, так как CVehicle - абстрактный класс.
(*it)->move();
*it позволяет получить по итератору объект, который хранится в листе. Он имеет тип указатель на CVehicle. Однако в листе конкретные объекты разных типов. Для всех типов виртуальный метод move переопределен. Поэтому при работе программа печатает
© Цитата:
The car moves. The ship moves. The plane moves.

То есть вызываются 3 разные функции move.
5
Спасибо большое)), № 175492 удалили по моему запросу, были перебои с сервером и произошло дублирование, но я успел посмотреть все ответы))
давно
Профессор
230118
3054
21.12.2009, 22:59
общий
S K A L T :
Если будут еще вопросы, спрашивайте на мини-форуме.
Неизвестный
22.12.2009, 13:47
общий
Назрело ещё два вопроса:
1)как ввести в основной программе поле Port
и затем вывести его?
я написал так
korablik->SetPort('10');
string p =korablik->GetPort();
cout << p;
но это не правильно, так как обращатся к полям наследников я так не могу.
2)
Можно ли написать вместо Set и Get в виртуальном классе вот так:
virtual void input(){
cin>>price;
cin>>velocity;
cin>>prodYear; } а затем уже описать ввод в наследниках:
void CShip::input(){ CVehicle::input();
cin>>passengers; cin>>port;}
Это не будет считаться ошибкой?
Если такой вариант возможен то как вывести поле port? пишу так:

void CShip::print(){ CVehicle::print();
cout<<passengers; cout<<port;} но выводит пустую строку.
давно
Профессор
230118
3054
22.12.2009, 16:27
общий
S K A L T :
1) Можно сразу написать правильные типы
CCar *mashinka=new CCar();
CPlane *samoletik=new CPlane();
CShip *korablik=new CShip();
Тогда вызовы get/set будут работать нормально. Все указатели на эти классы неявно преобразуются в указатель на CVehicle.
2) Да, это нормально.
давно
Профессор
230118
3054
22.12.2009, 16:30
общий
S K A L T :
void CShip::input(){
CVehicle::input();
cout<<"Passengers=";
cin>>passengers;
cout<<"Port=";
cin>>port;
}
В основной программе
korablik->input();
korablik->print();
должно работать
давно
Профессор
230118
3054
22.12.2009, 16:32
общий
S K A L T :
[i][b]В SetPort('10') нельзя употреблять такие кавычки ' '. Только " "![/b][/i]
давно
Профессор
230118
3054
22.12.2009, 16:33
общий
S K A L T :
[i][b]Почитайте Страуструпа![/b][/i]
Неизвестный
22.12.2009, 17:02
общий
' ' и " " путаю иногда, но это не столь важно, мне кажется когда используешь string то вывод должен быть каким то другим
попробовал просто в новой программе написать так:
#include <string>
#include <conio>
main(){
string p;
cin>>p;
cout<<p;
getch();}
На что он мне вывел пустоту .
Дело в том что я ввел строку, затем произошла задержка экрана и только потом он вывел перемунную p. В чем проблема я не понимаю.
Неизвестный
22.12.2009, 17:06
общий
Странно написал после cout<<p ещё раз cin>>p; вывести то вывелось но приходится ещё раз вводить p
давно
Профессор
230118
3054
22.12.2009, 17:27
общий
S K A L T :
Еще один раз вводить р не надо. getch() вызывает ожидание ввода.
давно
Профессор
230118
3054
22.12.2009, 17:36
общий
S K A L T :
Поток вывода буферный. Вывод происходит на экран, когда работает процедура flush. Ее можно форсировать. Например, добавить в поток перевод строки. out<<p <<endl;
Неизвестный
22.12.2009, 19:16
общий
Вот спасибо . Вы наверное самый лучший эксперт этой рассылки)). С вами всё становится понятно . Очень вам благодарен.
Форма ответа