Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 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; просмотров: 127; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 13.59.243.194 (0.063 с.) |