Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Ссылочная композиция — логическое объединение
Некоторые виды композиции не предполагают ответственности на уничтожение дочернего объекта. Такая связь скорее является логическим объединением в группу, нежели жестким отношением целое-часть. Для дочерних объектов в логических объединениях свойственно вхождение сразу в несколько родительских объектов. В таком случае за уничтожение дочернего объекта отвечает кто-либо другой, а не родительский объект.
Если такая связь между объектами является постоянной, то, как правило, дочерний объект хранится по ссылке либо константной ссылке, которая передается в родительский объект при конструировании. Обычно, таким видам объектов не свойственно копирование и присвоение, и эти операции имеет смысл в явном виде запретить.
Ниже представлено логическое объединение между орудием (Weapon) и его типом, или моделью (WeaponType). Каждый экземпляр класса Weapon получает ссылку на тип орудия WeaponType в конструкторе, и эта ссылка сохраняется до конца жизни объекта орудия. Предполагается, что тип орудия просуществует дольше любого из орудий. Это ограничение должно обеспечиваться внешним по отношению к рассматриваемым классам кодом.
weapontype.hpp
#ifndef _WEAPONTYPE_HPP_ #define _WEAPONTYPE_HPP_
//************************************************************************
class WeaponType { /*-----------------------------------------------------------------*/
public:
/*-----------------------------------------------------------------*/
// Конструктор WeaponType (double _caliber, int _maxAmmo);
// Удаленные конструктор копий и оператор присвоения WeaponType (const WeaponType &) = delete; WeaponType & operator = (const WeaponType &) = delete;
// Метод доступа к калибру double getCaliber () const;
// Метод доступа к максимальному числу зарядов int getMaxAmmo () const;
/*-----------------------------------------------------------------*/
private:
/*-----------------------------------------------------------------*/
// Калибр орудия const double m_caliber;
// Максимальное число зарядов const int m_maxAmmo;
/*-----------------------------------------------------------------*/
};
//************************************************************************
// Реализация метода доступа к калибру inline double WeaponType::getCaliber () const { return m_caliber; }
//************************************************************************
// Реализация метода доступа к максимальному числу зарядов inline int WeaponType::getMaxAmmo () const { return m_maxAmmo; }
//************************************************************************
#endif //_WEAPONTYPE_HPP_
weapontype.cpp
#include "weapontype.hpp"
#include <stdexcept>
//************************************************************************
// Реализация конструктора WeaponType::WeaponType (double _caliber, int _maxAmmo) : m_caliber(_caliber), m_maxAmmo(_maxAmmo) { // Инвариант: калибр является положительным числом if (_caliber <= 0.0) throw std::logic_error("Expecting a positive caliber");
// Инвариант: максимальный заряд является положительным числом if (_maxAmmo < 1) throw std::logic_error("Expecting at least 1 as a maximum ammo"); }
//************************************************************************
weapon.hpp
#ifndef _WEAPON_HPP_ #define _WEAPON_HPP_
//************************************************************************
class WeaponType;
//************************************************************************
class Weapon {
/*-----------------------------------------------------------------*/
public:
/*-----------------------------------------------------------------*/
// Конструктор Weapon (const WeaponType & _type, int _initialAmmo = 0); // ^ ссылка на дочерний объект приходит в конструкторе
// Удаленные конструктор копий и оператор присвоения Weapon (const Weapon &) = delete; Weapon & operator = (const Weapon &) = delete;
// Метод доступа к типу орудия const WeaponType & getType () const;
// Метод доступа к количеству оставшихся зарядов int getCurrentAmmo () const;
// Метод зарядки орудия. Возвращает количество оставшихся зарядов int loadAmmo (int _ammo);
// Методы определения полноты заряда / отсутствия зарядов bool hasFullAmmo () const; bool hasNoAmmo () const;
// Метод имитации выстрела орудия bool tryShoot ();
/*-----------------------------------------------------------------*/
private:
/*-----------------------------------------------------------------*/
// Ссылка на дочерний объект — тип орудия const WeaponType & m_type;
// Количество оставшихся зарядов int m_currentAmmo;
/*-----------------------------------------------------------------*/
};
//************************************************************************
// Реализация метода доступа к типу орудия inline const WeaponType & Weapon::getType () const { return m_type; }
//************************************************************************
// Реализация метода доступа к количеству оставшихся зарядов Inline int Weapon::getCurrentAmmo () const { return m_currentAmmo; }
//************************************************************************
#endif //_WEAPON_HPP_
weapon.cpp
#include "weapon.hpp" #include "weapontype.hpp"
//************************************************************************
// Реализация конструктора Weapon::Weapon (const WeaponType & _type, int _initialAmmo) : m_type(_type) // запоминаем ссылку на дочерний объект , m_currentAmmo(_initialAmmo) { }
//************************************************************************
// Реализация метода определения полноты заряда bool Weapon::hasFullAmmo () const { // Сравниваем количество оставшихся зарядов с // максимально возможным для данного типа орудия return m_currentAmmo == getType().getMaxAmmo(); // ^ извлекаем максимум из дочернего объекта }
//************************************************************************
// Реализация метода определения отсутствия зарядов bool Weapon::hasNoAmmo () const { return m_currentAmmo == 0; }
//************************************************************************
// Реализация метода загрузки зарядов int Weapon::loadAmmo (int _ammo) { // Определяем количество не хватающих до полной загрузки зарядов int maxAmmo = getType().getMaxAmmo(); int freeAmmoSpace = maxAmmo - m_currentAmmo;
// Достаточно ли имеется зарядов до полной загрузки? if (_ammo >= freeAmmoSpace) { // Возвращаем число неиспользованных зарядов m_currentAmmo = maxAmmo; return _ammo - freeAmmoSpace; } Else { // Переданного количества зарядов не хватит для полной загрузки m_currentAmmo += _ammo; return 0; } }
//************************************************************************
// Реализация метода имитации выстрела bool Weapon::tryShoot () { // Имеется ли хоть один заряд? if (hasNoAmmo()) // Без зарядов стрелять трудно:-( return false;
// Выстрел произведен. Уменьшаем число оставшихся зарядов на 1. -- m_currentAmmo; return true; }
//************************************************************************
test_weapons.cpp
#include "weapon.hpp" #include "weapontype.hpp"
#include <cassert>
int main () { // Создаем тип орудия — калибр 125мм, максимум 5 зарядов WeaponType * pType = new WeaponType(125.0, 5);
// Создаем два орудия данного типа без начального заряда Weapon * pWeapon1 = new Weapon(* pType); Weapon * pWeapon2 = new Weapon(* pType);
// Заряжаем первое орудие максимально, убеждаемся, что орудие забрало // зарядов, соответствующее максимально возможному для типа орудия int totalAmmo = 100; totalAmmo = pWeapon1->loadAmmo(totalAmmo); assert(totalAmmo == (100 - pType->getMaxAmmo()));
// Заряжаем второе орудие только 1 снарядом pWeapon2->loadAmmo(1);
// Делаем выстрел из первого орудия, убеждаемся, что число зарядом уменьшилось на 1 assert(pWeapon1->getCurrentAmmo() == pType->getMaxAmmo()); bool success = pWeapon1->tryShoot(); assert(success && pWeapon1->getCurrentAmmo() == (pType->getMaxAmmo() - 1));
// Делаем выстрел из второго орудия assert(pWeapon2->getCurrentAmmo() == 1); success = pWeapon2->tryShoot(); // Убеждаемся, что выстрел произведен, и что зарядов в орудии не осталось assert(success && pWeapon2->hasNoAmmo());
// Второй выстрел из второго орудия не получится success = pWeapon2->tryShoot(); assert(! success);
// Уничтожаем орудия delete pWeapon1; delete pWeapon2;
// Уничтожаем тип орудия delete pType; }
|
||||||
Последнее изменение этой страницы: 2017-02-17; просмотров: 136; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.149.243.106 (0.038 с.) |