Разрываемая ссылочная композиция 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Разрываемая ссылочная композиция



 

Ссылочные связи между объектами также не обязательно являются постоянными и могут изменяться в течение жизни объектов. Аналогично предыдущему примеру, такое отношение моделируют при помощи указателя на дочерний объект. Однако в данном случае объект-родитель не является ответственным за уничтожение дочернего объекта.

 

Ниже приведен пример класса, моделирующего вертолетную площадку (HelicopterPad). Площадка может принимать только один приземлившийся вертолет (Helicopter). Объект-вертолет может приземляться на площадку через вызов метода land, а затем покидать ее после вызова unland. Площадка должна проверять, что на ней может быть приземлен единственный вертолет, и что взлет возможен только, если вертолет до этого приземлился.

 

При этом уничтожение вертолета никогда не является задачей вертолетной площадки. В данном случае пропадает необходимость в наличии у класса-площадки собственного деструктора, поскольку никаких действий не требуется.

 

 

Helicopterpad.hpp

 

#ifndef _HELICOPTERPAD_HPP_

#define _HELICOPTERPAD_HPP_

 

//************************************************************************

 

#include "point3d.hpp"

 

//************************************************************************

 

// Форвардное объявление класса-вертолета.

// Его содержимое не требуется для объявления класса-площадки.

class Helicopter;

 

//************************************************************************

 

// Класс-площадка

class HelicopterPad

{

 

/*-----------------------------------------------------------------*/

 

public:

 

/*-----------------------------------------------------------------*/

 

// Конструктор — задает координату местоположения, но не задает вертолета

HelicopterPad (Point3D _location);

 

// Запрещенные конструктор копий и оператор присвоения

HelicopterPad (const HelicopterPad &) = delete;

HelicopterPad & operator = (const HelicopterPad &) = delete;

 

// Метод доступа к местоположению площадки

Point3D getLocation () const;

 

// Метод подтверждения приземления вертолета

bool hasLanded () const;

 

// Метод доступа к возможно приземлившемуся вертолету

Helicopter * getLanded () const;

 

// Метод регистрации приземления вертолета

void land (Helicopter & _helicopter);

 

// Метод регистрации взлета вертолета

void unland ();

 

/*-----------------------------------------------------------------*/

 

private:

 

/*-----------------------------------------------------------------*/

 

// Координаты местоположения площадки.

// В отличие от вертолета, координаты площадки не могут изменяться

const Point3D m_location;

 

// Необязательная связь с приземлившимся объектом-вертолетом

Helicopter * m_pLanded;

 

/*-----------------------------------------------------------------*/

 

};

 

//************************************************************************

 

// Реализация метода доступа к местоположению площадки

inline Point3D

HelicopterPad::getLocation () const

{

return m_location;

}

 

//************************************************************************

 

// Реализация метода подтверждения приземления вертолета

inline bool HelicopterPad::hasLanded () const

{

// Если вертолет приземлился, значение указателя будет отлично от nullptr

return m_pLanded!= nullptr;

}

 

//************************************************************************

 

// Реализация метода доступа к возможно приземлившемуся вертолету

inline Helicopter *

HelicopterPad::getLanded () const

{

// Даже если вертолет не приземлился, все корректно — метод вернет nullptr

return m_pLanded;

}

 

//************************************************************************

 

#endif //_HELICOPTERPAD_HPP_

 

 

helicopterpad.cpp

 

#include "helicopterpad.hpp"

#include "helicopter.hpp"

#include "point3d.hpp"

 

#include <stdexcept>

 

//************************************************************************

 

// Реализация конструктора

HelicopterPad::HelicopterPad (Point3D _location)

: m_location(_location),

m_pLanded(nullptr) // Изначально вертолет не приземлялся

{

}

 

//************************************************************************

 

// Реализация метода регистрации приземления вертолета

void HelicopterPad::land (Helicopter & _helicopter)

{

// Убеждаемся, что другой вертолет не приземлялся

if (m_pLanded)

throw std::logic_error("Something has already landed on this pad");

 

// Подводим вертолет к точке приземления

_helicopter.moveTo(getLocation());

 

// Создаем связь между объектами —
// запоминаем адрес объекта-вертолета в объекте-площадке

m_pLanded = & _helicopter;

}

 

//************************************************************************

 

// Реализация метода регистрации взлета вертолета

void HelicopterPad::unland ()

{

// Убеждаемся, что вертолет приземлялся

if (! m_pLanded)

throw std::logic_error("No helicopter is currently landed");

 

// Вертолет должен взлететь на 7м строго над площадкой

m_pLanded->moveTo(

Point3D(

getLocation().getX(),

getLocation().getY(),

getLocation().getZ() + 7.0

)

);

 

// Разрываем связь между объектами обнулением указателя

m_pLanded = nullptr;

}

 

//************************************************************************

 

test_pads.cpp

 

#include "helicopterpad.hpp"

#include "helicopter.hpp"

 

#include <cassert>

 

int main ()

{

// Создаем вертолетную площадку

HelicopterPad * pHeliPad = new HelicopterPad(Point3D(1.0, 2.0, 0.0));

 

// Изначально на площадке никто не приземлен

assert(! pHeliPad->hasLanded());

 

// Создаем вертолет

Helicopter * pHelicopter = new Helicopter(1);

 

// Приземляем вертолет на площадке

pHeliPad->land(* pHelicopter);

 

// Убеждаемся, что на площадке находится наш вертолет

assert(pHeliPad->hasLanded() && pHeliPad->getLanded() == pHelicopter);

 

// Убеждаемся, что текущее местоположение вертолета совпадает с местом площадки

Point3D location = pHelicopter->getCurrentPosition();

assert(location == pHeliPad->getLocation());

 

// Взлетаем

pHeliPad->unland();

 

// На площадке не должно остаться вертолета

assert(! pHeliPad->hasLanded());

 

// Координаты X/Y вертолета должны совпадать с координатами площадки,

// однако координата Z должна отличаться (вертолет взлетает идеально вверх)

Point3D newLocation = pHelicopter->getCurrentPosition();

assert(newLocation.getX() == location.getX() &&

newLocation.getY() == location.getY() &&

newLocation.getZ() > location.getZ());

 

// Уничтожаем площадку и вертолет

delete pHeliPad;

delete pHelicopter;

}



Поделиться:


Последнее изменение этой страницы: 2017-02-17; просмотров: 151; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.220.178.207 (0.015 с.)