Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Композиция с разрываемой связьюСодержание книги
Поиск на нашем сайте
Некоторые виды отношений целое-часть не являются постоянными. Дочерний объект может прикрепляться к родительскому в течение его жизни, а при необходимости — отцепляться и прикрепляться к другому родительскому объекту. Такое поведение свойственно отношениям, в которых дочерний объект имеет существенную долю обязанностей по сравнению с родительским объектом, и имеется практический смысл в его существовании вне родительского либо с другим родителем. При этом родительский объект по-прежнему может отвечать за уничтожение дочернего.
Ниже представлен класс, моделирующий вертолет (Helicopter). Вертолет имеет уникальный числовой номер. Вертолет находится в конкретный момент времени по конкретным координатам и его нос направлен под конкретным углом относительно осей координат. На вертолет может быть установлено необязательное к наличию орудие (объект Weapon). При наличии орудия, вертолет может производить выстрелы, в противном случае — только летать.
С точки зрения хранения данных в памяти, единственным способом для реализации такой необязательной связи между объектами является хранение указателя на дочерний объект в памяти родительского. Указатель будет адресовать конкретный дочерний объект, если связь установлена. При отсутствии связи значение указателя будет равно nullptr.
Связь между объектами Helicopter и Weapon не является обязательной. Она может устанавливаться внешне через вызов метода installWeapon, а затем разрываться через вызов deinstallWeapon. Во избежание ошибок объект-вертолет должен проверять, что может быть установлено только одно орудие, а также гарантировать, что снять орудие можно только после его установки. Если орудие прикреплено к вертолету на момент его уничтожения, орудие уничтожается вместе с ним.
helicopter.hpp
#ifndef _HELICOPTER_HPP_ #define _HELICOPTER_HPP_
//************************************************************************
#include "point3d.hpp" #include "vector3d.hpp"
//************************************************************************
// Форвардное объявление класса-орудия. При определении класса-вертолета, // // Не делаем #include "weapon.h" до момента реальной необходимости // // Однако мы включили определение класса-точки и класса-вектора,
class Weapon;
//************************************************************************
class Helicopter {
/*-----------------------------------------------------------------*/
public:
/*-----------------------------------------------------------------*/
// Конструктор — передаем номер, начальный угол и позицию, орудие не предусмотрено Helicopter ( int _machineID , Vector3D _initialAngle = Vector3D() , Point3D _initialPosition = Point3D() );
// Запрещенные конструктор копий и оператор присвоения Helicopter (const Helicopter &) = delete; Helicopter & operator = (const Helicopter &) = delete;
// Деструктор ~Helicopter ();
// Метод, возвращающий номер вертолета int getMachineID () const;
// Метод подтверждения наличия орудия bool hasWeapon () const;
// Метод доступа к установленному орудию Weapon * getWeapon () const;
// Метод установки орудия void installWeapon (Weapon & _weapon);
// Метод снятия орудия void deinstallWeapon ();
// Метод, осуществляющий пробу выстрела по заданной целевой координате bool tryShootingTargetAt (Point3D _p);
// Методы доступа и изменения текущей позиции Point3D getCurrentPosition () const; void moveTo (Point3D _p);
// Методы доступа и изменения текущего угла по отношению к координатным осям Vector3D getCurrentAngle () const; void turnTo (Vector3D _angle);
/*-----------------------------------------------------------------*/
private:
/*-----------------------------------------------------------------*/
// Дочерний объект-орудие – связь не является обязательной, может быть nullptr Weapon * m_pWeapon;
// Угол направления носа вертолета Vector3D m_currentAngle;
// Текущие координаты местоположения вертолета Point3D m_position;
// Уникальный числовой номер вертолета const int m_machineID;
/*-----------------------------------------------------------------*/
};
//************************************************************************
// Реализация метода, возвращающего номер вертолета Inline int Helicopter::getMachineID () const { return m_machineID; }
//************************************************************************
// Реализация метода доступа к текущей позиции inline Point3D Helicopter::getCurrentPosition () const { return m_position; }
//************************************************************************
// Реализация метода изменения текущей позиции Inline void Helicopter::moveTo (Point3D _p) { m_position = _p; }
//************************************************************************
// Реализация метода доступа к текущему углу inline Vector3D Helicopter::getCurrentAngle () const { return m_currentAngle; }
//************************************************************************
// Реализация метода изменения текущего угла Inline void Helicopter::turnTo (Vector3D _angle) { m_currentAngle = _angle; }
//************************************************************************
// Реализация метода подтверждения наличия орудия Inline bool Helicopter::hasWeapon () const { // Если орудие установлено, значение указателя будет отлично от nullptr return m_pWeapon!= nullptr; }
//************************************************************************
// Реализация метода доступа к установленному орудию Inline Weapon * Helicopter::getWeapon () const { // Даже если орудия не установлено, все корректно — метод вернет nullptr return m_pWeapon; }
//************************************************************************
#endif //_HELICOPTER_HPP_
helicopter.cpp
#include "helicopter.hpp" #include "weapon.hpp" // Включаем полное определение класса-орудия лишь сейчас, // поскольку для реализации методов класса-вертолета используется // содержимое класса-орудия (для выстрела, для уничтожения)
#include <stdexcept>
//************************************************************************
// Реализация конструктора Helicopter::Helicopter ( int _machineID , Vector3D _initialAngle , Point3D _initialPosition ) // Копируем номер, угол и координаты : m_machineID(_machineID) , m_currentAngle(_initialAngle) , m_position(_initialPosition) , m_pWeapon(nullptr) // <- Изначально орудие не устанавливается { }
//************************************************************************
// Реализация деструктора Helicopter::~Helicopter () { // Уничтожаем орудие, если оно установлено. // Если орудия не установлено, ничего страшного, delete nullptr игнорируется delete m_pWeapon; }
//************************************************************************
// Реализация метода установки орудия void Helicopter::installWeapon (Weapon & _weapon) { // Убеждаемся, что никакое другое орудие еще не было установлено if (hasWeapon()) throw std::logic_error("Weapon is already installed on the helicopter");
// Создаем связь между объектами: m_pWeapon = & _weapon; }
//************************************************************************
// Реализация метода снятия орудия void Helicopter::deinstallWeapon () { // Убеждаемся, что орудие было установлено if (! hasWeapon()) throw std::logic_error("Weapon was not installed on the helicopter");
// Разрываем связь между объектами через обнуление указателя m_pWeapon = nullptr;
// Примечание: при таком разрыве связи внешний код должен гарантировать // освобождение объекта-орудия, поскольку вертолет больше за него не отвечает }
//************************************************************************
// Реализация метода, осуществляющего пробу выстрела по заданной целевой координате bool Helicopter::tryShootingTargetAt(Point3D _p) { // Если орудия не установлено, выстрелить не получится if (! hasWeapon()) return false;
// Изменяем угол носа вертолета таким образом, чтобы вертолет смотрел на цель turnTo( Vector3D( _p.getX() - m_position.getX(), _p.getY() - m_position.getY(), _p.getZ() - m_position.getZ() ) );
// Пробуем выстрелить из орудия. // Логика учета количества зарядов уже учтена в реализации класса-орудия return m_pWeapon->tryShoot(); }
//************************************************************************
test_helicopter.cpp
#include "helicopter.hpp" #include "weapontype.hpp" #include "weapon.hpp"
#include <cassert>
int main () { // Создаем два объекта-вертолета Helicopter * pHelicopter1 = new Helicopter(1); Helicopter * pHelicopter2 = new Helicopter(2);
// Создаем тип орудия WeaponType * pWeaponType = new WeaponType(125.0, 5);
// Вооружаем первый вертолет орудием с одним начальным зарядом pHelicopter1->installWeapon(* new Weapon(* pWeaponType, 1)); assert(pHelicopter1->getWeapon()->getCurrentAmmo() == 1);
// Пробуем выстрелить c первого вертолета. // Первый выстрел успешен, а орудие разряжено. bool result = pHelicopter1->tryShootingTargetAt(Point3D(2.0, 2.0, 2.0)); assert(result && pHelicopter1->getWeapon()->hasNoAmmo());
// Пробуем выстрелить еще раз с первого вертолета. // Второй выстрел завершается неудачей, поскольку нет зарядов в орудии result = pHelicopter1->tryShootingTargetAt(Point3D(3.0, 3.0, 3.0)); assert(! result);
// Пробуем выстрелить со второго вертолета, однако терпим неудачу, // поскольку никакого орудия на нем не установлено result = pHelicopter2->tryShootingTargetAt(Point3D(4.0, 4.0, 4.0)); assert(! result);
// Куда же направлены носы наших вертолетов? // - первый вертолет имеет вооружение, и поворачивается перед попыткой выстрела, // соответственно, его нос направлен в сторону координаты последней цели // - второй вертолет не имеет установленного орудия, и не поворачивается assert(pHelicopter1->getCurrentAngle() == Vector3D(3.0, 3.0, 3.0)); assert(pHelicopter2->getCurrentAngle() == Vector3D(0.0, 0.0, 0.0));
// Уничтожаем оба вертолета. Орудие уничтожается вместе с первым вертолетом delete pHelicopter1; delete pHelicopter2;
// Уничтожаем тип орудия delete pWeaponType; }
|
||
|
Последнее изменение этой страницы: 2017-02-17; просмотров: 180; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.214 (0.006 с.) |