У вас вопросы?
У нас ответы:) SamZan.net

Лабораторная работа 3

Работа добавлена на сайт samzan.net:

Поможем написать учебную работу

Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 29.12.2024

Лабораторная работа3.  

Объектная модель: проектирование структуры и реализация ключевых классов

Цели лабораторной работы:

  1.  Понятийный анализ предметной области, выявление ключевых информационных сущностей. Предполагается выявить основные классы, описательные атрибуты классов, а также связи между классами исходя из ранее проанализированных и специфицированных требований.
  2.  Создание статического ракурса модели информационной системы в виде иерархии взаимосвязанных классов. Предполагается спецификация иерархии классов в виде UML-диаграмм.
  3.  Отображение модели ключевых классов системы в виде программных конструкций на языке С++ и проверка работоспособности реализации при помощи тестовой программы.

Ход лабораторной работы:

  1.  Выявление кандидатов в классы, описывающие предметную область:
  •  Выписать часто встречающиеся существительные в описании требований.
  •  Выделить в отдельный список те из выписанных существительных, которые имеют явное четко очерченное значение количественного или качественного характера – такие существительные являются кандидатами в атрибуты.
  •  Выделить в отдельный список те из выписанных существительных, которые можно отнести к одной из следующих смысловых групп – такие существительные являются явными кандидатами в классы:
  •  понятие, концепция;
  •  предмет;
  •  событие;
  •  организация;
  •  роль;
  •  местоположение;
  •  взаимодействие.
  •  По остальным существительным решение может быть принято позже.

  1.  Метод CRC-карточек:

Для оценки корректности выявления каждого конкретного класса следует дать ответы на следующие вопросы:

  •  Каковы обязанности класса?

Идеальным случаем является наличие у каждого класса ровно 1 четкой обязанности.

Если обязанности сформулировать не получается, возможно существительное не является классом.

Если обязанностей несколько, возможно класс слишком большой и его следует разбить на несколько более мелких с 1 четкой обязанностью.

  •  С какими другими классами сотрудничает класс?

Наличие других классов, с которыми взаимодействует класс, свидетельствует о правильном выявлении, т.к. атрибуты связей с другими классами не имеют.

Если класс не взаимодействует ни с кем, маловероятно, что класс представляет собой объект-сущность. Отсутствие связей вполне допустимо для классов-значений.

  1.  Спецификация структуры классов:
  •  Используя программу StarUML, создать новую модель, содержащую диаграмму классов
  •  Добавить пустые классы-заготовки для всех выявленных классов.
  •  Выявить и специфицировать на диаграмме описательные атрибуты классов:
  •  Атрибут должен иметь имя и тип данных.
  •  Рекомендуется всем атрибутам назначить закрытую видимость.
  •  Тип данных описательного атрибута наиболее часто является элементарным (число, строка, перечисление).
  •  Во многих задачах встречаются атрибуты неэлементарных типов, представляющие собой объекты-значения, т.е. объекты, не имеющие индивидуальности, равенство между которыми определяется равенством всех атрибутов. Для распространенных случаев, таких как адрес, дата, деньги, новые классы на диаграмме вводить смысла не имеет, т.к. их структура очевидна. 
  •  Выявить и обозначить на диаграмме отношения агрегации между классами:
  •  агрегация – это отношение целое-часть: если нельзя сказать, что объект класса является частью объекта другого класса, то отношение не является агрегацией;
  •  символ агрегации – ромбик – отображается на стороне объекта-контейнера;
  •  подвиды агрегации ExclusiveOwns (безраздельное владение) и Owns (владение) обозначаются закрашенным ромбиком, а Has и Member – незакрашенным;
  •  конкретный вид агрегации можно подчеркнуть при помощи стереотипов (дополнительный текст на соединительных стрелках);
  •  обязательно указать кратность агрегации ( 1..1, 1..*, *..*, );
  •  допускается отношение циклической агрегации, если один из объектов класса может содержать объекты того же самого класса;
  •  если между классами существует более чем одно отношение агрегации, следует уточнить отношение при помощи явного имени либо комментария;
  •  Выявить и обозначить на диаграмме отношения ассоциации между классами:
  •  простая ассоциация существует между классами, объекты которых либо взаимодействуют между собой во время выполнения какого-либо сценария, либо логически связаны, однако нельзя отнести отношение к агрегации;
  •  ассоциация может быть:
  •  двунаправленной, если оба объекта инициируют взаимодействие друг с другом;
  •  однонаправленной, если только один из объектов инициирует взаимодействие;
  •  без направления, если смысл ассоциации акцентируется не на взаимодействии, а на некоторой логической связи;
  •  обязательно указать кратность ассоциации ( 1..1, 1..*, *..*, );
  •  аналогично агрегациям, допускается циклическая ассоциация, и более чем одна ассоциация между двумя классами, что также следует уточнить именем ( где уместно – именами ассоциативных ролей на концах стрелок );
  •  если между двумя классами существует ассоциация с кратностью *..*, следует задуматься о возможных ассоциативных классах – т.е., вспомогательных классах, моделирующих конкретную пару объектов ( типичный признак: конкретная пара объектов имеет характерные атрибуты )
  •  Выявить и обозначить на диаграмме отношения обобщения между классами: 
  •  правильный случай: можно сказать, что подкласс является подвидом суперкласса;
  •  правильный случай: объект суперкласса можно заменить объектом подкласса;
  •  правильный случай: подкласс расширяет обязанности суперкласса;
  •  неправильный случай: наследование похожих атрибутов без наличия связи между обязанностями классов;
  •  неправильный случай: классы отличаются лишь малым набором свойств, не существенным для рассматриваемой задачи.

На данном этапе можно остановиться, если устраивает оценка “удовлетворительно. Для получения более высокой оценки следует выполнить остальные задания.

  1.  Отображение основных абстракций на языке программирования C++:
  •  Для всех выявленных классов создать на языке C++ декларации:
  •  классов;
  •  атрибутов;
  •  конструкций, реализующих отношения между классами:
  •  отношения обобщения в виде наследования классов;
  •  отношения агрегации и ассоциации, используя механизмы языка программирования, наиболее близко отражающие семантику диаграммы (например, ссылки, указатели, коллекции, объекты smart pointers, и т.п.).
  •  Снабдить все декларации качественными комментариями (по возможности, на английском языке).
  •  Создать необходимые для организации работы класса объявления и определения ключевых операций, учитывающие семантику всех атрибутов и отношений:
  •  конструктор(ы);
  •  деструктор;
  •  операции-селекторы для описательных атрибутов, для навигации по связям;
  •  операции для формирования связей (если имеются отношения с кратностью 1..*, *..* , либо связь является необязательной).

Заголовки классов следует размещать в отдельных заголовочных файлах, а реализации методов классов следует размещать в отдельных C++ файлах, имена которых должны соответствовать именам классов (например, класс Reservation – объявление в reservation.hpp, реализация в reservation.cpp) ;

  1.  Формирование тестовой программы, подтверждающей работоспособность модели:
  •  Составьте консольную тестовую С++ программу, отражающую несколько реалистичных примеров структуры объектной модели, использующих большинство созданных классов:
  •  Программа должна создавать некоторое количество тестовых объектов модели, вручную организовывать связи между ними. Вводить данные об объектах извне во время выполнения не требуется, конкретный состав объектной модели примера может быть жестко задан в коде тестовой программы.
  •  Программа должна уметь обходить созданную модель от вершины иерархии целое-часть ко всем листьям, и при этом распечатывать данные об посещаемых во время обхода объектах (адрес, тип, значения атрибутов).
  •  Вложенность объектов по иерархии целое-часть уместно выразить при помощи отступов или любым другим подходящим способом.
  •  Распечатка может осуществляться или на экран, или в дисковый файл.

Пример простейшей объектной модели

Ниже приведена UML-диаграмма простейшей объектной модели, предназначенной для хранения данных о заказах товаров в магазине. 

Созданные классы имеют следующие обязанности:

  1.  Класс Shop – представляет собой информацию о магазине, существенную для данного примера. Этот класс будет создаваться только в одном экземпляре за время выполнения программы.
  2.  Класс Order – представляет заказ в магазине, имеет уникальный идентификатор, время регистрации. Имеется ярко выраженная операция вычисления стоимости.
  3.  Класс Item – представляет строку заказа: товар, количество штук, цену на момент заказа.
  4.  Класс Product – представляет собой описание товара, включая уникальный номер, название, описание, код страны происхождения, а также текущую стоимость.
  5.  Класс Money – тип-значение, представляющий денежную единицу с целой частью и копейками.

Ниже приведена упрощенная реализация данной модели на языке С++.

money.hpp

#ifndef _MONEY_HPP_

#define _MONEY_HPP_

//-----------------------------------------------------------------------------

#include <string>

//-----------------------------------------------------------------------------

class Money

{

//-------------------------

public:

//-------------------------

   Money ();

   Money ( unsigned int _integralPart, unsigned char _fractionalPart );

   static Money fromString ( const std::string & _moneyAsText );

//-------------------------

   std::string toString () const;

   bool operator == ( const Money & _m ) const;

   Money operator + ( Money const & _m ) const;

   Money operator * ( unsigned int _n ) const;

//-------------------------

private:

//-------------------------

   unsigned int m_integralPart;

   unsigned char m_fractionalPart;

//-------------------------

};

//-----------------------------------------------------------------------------

#endif //  _MONEY_HPP_

money.cpp

//-----------------------------------------------------------------------------

#include "money.hpp"

#include <boost/lexical_cast.hpp>

//-----------------------------------------------------------------------------

Money::Money ()

   :   m_integralPart( 0 ),

       m_fractionalPart( 0 )

{

}

//-----------------------------------------------------------------------------

Money::Money ( unsigned int _integralPart, unsigned char _fractionalPart )

   :   m_integralPart( _integralPart ),

       m_fractionalPart( _fractionalPart )

{

}

//-----------------------------------------------------------------------------

Money 

Money::fromString ( const std::string & _moneyAsText )

{

   double money = boost::lexical_cast< double >( _moneyAsText );

   if ( money < 0. )

       throw std::exception();

   unsigned int integralPart = static_cast< unsigned int >( money );

   unsigned char fractionalPart = static_cast< unsigned char >(

( money - integralPart ) * 100.0 

);

   return Money( integralPart, fractionalPart );

}

//-----------------------------------------------------------------------------

std::string 

Money::toString () const

{

   char buf[ 100 ];

   sprintf( buf, "%d.%02d", m_integralPart, m_fractionalPart );

   return buf;

}

//-----------------------------------------------------------------------------

bool 

Money::operator == ( const Money & _m ) const

{

   return m_integralPart   == _m.m_integralPart &&

          m_fractionalPart == _m.m_fractionalPart;

}

//-----------------------------------------------------------------------------

Money 

Money::operator + ( Money const & _m ) const

{

   unsigned int resultIngeralPart = m_integralPart + _m.m_integralPart;

   

   unsigned char resultFractionalPart = m_fractionalPart + _m.m_fractionalPart;

   if ( resultFractionalPart >= 100 )

   {

       ++resultIngeralPart;

       resultFractionalPart %= 100;

   }

   return Money( resultIngeralPart, resultFractionalPart );

}

//-----------------------------------------------------------------------------

Money 

Money::operator * ( unsigned int _n ) const

{

   unsigned int moneyInCents = m_integralPart * 100 + m_fractionalPart;

   moneyInCents *= _n;

   return Money( moneyInCents / 100, moneyInCents % 100 );

}

//-----------------------------------------------------------------------------

product.hpp

#ifndef _PRODUCT_HPP_

#define _PRODUCT_HPP_

//-----------------------------------------------------------------------------

#include "money.hpp"

#include <string>

//-----------------------------------------------------------------------------

class Product

{

//-------------------------

public:

//-------------------------

   Product (

       unsigned int _uniqueID,

       const std::string & _name,

       const std::string & _description,

       const Money & _initialPrice

   );

//-------------------------

   unsigned int getUniqueID () const;

   const std::string & getName () const;

   const std::string & getDescription () const;

   const Money & getCurrentPrice () const;

   void setPrice ( const Money & _newPrice );

//-------------------------

private:

//-------------------------

   const unsigned int m_uniqueID;

   const std::string m_name;

   const std::string m_description;

   Money m_currentPrice;

//-------------------------

};

//-----------------------------------------------------------------------------

inline

unsigned int

Product::getUniqueID () const

{

   return m_uniqueID;

}

//-----------------------------------------------------------------------------

inline

const std::string &

Product::getName () const

{

   return m_name;

}

//-----------------------------------------------------------------------------

inline

const std::string &

Product::getDescription () const

{

   return m_description;

}

//-----------------------------------------------------------------------------

inline

const Money &

Product::getCurrentPrice () const

{

   return m_currentPrice;

}

//-----------------------------------------------------------------------------

inline

void 

Product::setPrice ( const Money & _newPrice )

{

   m_currentPrice = _newPrice;

}

//-----------------------------------------------------------------------------

#endif //  _PRODUCT_HPP_

product.cpp

//-----------------------------------------------------------------------------

#include "product.hpp"

//-----------------------------------------------------------------------------

Product::Product (

   unsigned int _uniqueID,

   const std::string & _name,

   const std::string & _description,

   const Money & _initialPrice

)

   :   m_uniqueID( _uniqueID ),

       m_name( _name ),

       m_description( _description ),

       m_currentPrice( _initialPrice )

{

}

//-----------------------------------------------------------------------------

item.hpp

#ifndef _ITEM_HPP_

#define _ITEM_HPP_

//-----------------------------------------------------------------------------

#include "money.hpp"

//-----------------------------------------------------------------------------

class Product;

//-----------------------------------------------------------------------------

class Item

{

//-------------------------

public:

//-------------------------

   Item ( Product const & _product, unsigned int _quantity );

//-------------------------

   Product const & getProduct () const;

   unsigned int getQuantity () const;

   void setQuantity ( unsigned int _newQuantity );

   Money getPrice () const;

   Money getCost () const;

//-------------------------

private:

//-------------------------

   Product const & m_product;

   unsigned int m_quantity;

   Money const m_price;

//-------------------------

};

//-----------------------------------------------------------------------------

inline

Product const &

Item::getProduct () const

{

   return m_product;

}

//-----------------------------------------------------------------------------

inline

unsigned int 

Item::getQuantity () const

{

   return m_quantity;

}

//-----------------------------------------------------------------------------

inline

void 

Item::setQuantity ( unsigned int _newQuantity )

{

   m_quantity = _newQuantity;

}

//-----------------------------------------------------------------------------

inline

Money

Item::getPrice () const

{

   return m_price;

}

//-----------------------------------------------------------------------------

#endif // _ITEM_HPP_

item.cpp

//-----------------------------------------------------------------------------

#include "item.hpp"

#include "product.hpp"

//-----------------------------------------------------------------------------

Item::Item ( Product const & _product, unsigned int _quantity )

:    m_product( _product ),

        m_price( _product.getCurrentPrice() ),

        m_quantity ( _quantity )

{

}

//-----------------------------------------------------------------------------

Money

Item::getCost () const

{

   return m_price * m_quantity;

}

//-----------------------------------------------------------------------------

order.hpp

#ifndef _ORDER_HPP_

#define _ORDER_HPP_

//-----------------------------------------------------------------------------

#include "money.hpp"

#include <vector>

//-----------------------------------------------------------------------------

class Item;

class Product;

//-----------------------------------------------------------------------------

class Order

{

//-------------------------

public:

//-------------------------

   Order ( unsigned int _uniqueID, time_t _registeredAt );

   ~Order ();

//-------------------------

   unsigned int getUniqueID () const;

   time_t getRegistrationTime () const;

//-------------------------

   unsigned int getItemsCount () const;

   Item const & getItem ( unsigned int _itemIndex ) const;

   Item & newItem ( Product const & _item, unsigned int _quantity );

   void removeItem ( Item & _item );

//-------------------------

   Money getCost () const;

//-------------------------

private:

//-------------------------

   const unsigned int m_uniqueID;

   const time_t m_registeredAt;

   typedef std::vector< Item * > Items;

   Items m_items;

//-------------------------

};

//-----------------------------------------------------------------------------

inline

unsigned int 

Order::getUniqueID () const

{

   return m_uniqueID;

}

//-----------------------------------------------------------------------------

inline

time_t 

Order::getRegistrationTime () const

{

   return m_registeredAt;

}

//-----------------------------------------------------------------------------

inline

unsigned int 

Order::getItemsCount () const

{

   return m_items.size();

}

//-----------------------------------------------------------------------------

inline

Item const &

Order::getItem ( unsigned int _itemIndex ) const

{

   return * ( m_items.at( _itemIndex ) );

}

//-----------------------------------------------------------------------------

#endif //  _ORDER_HPP_

order.cpp

//-----------------------------------------------------------------------------

#include "order.hpp"

#include "item.hpp"

#include <algorithm>

#include <boost/checked_delete.hpp>

#include <exception>

//-----------------------------------------------------------------------------

Order::Order ( unsigned int _uniqueID, time_t _registeredAt )

   :   m_uniqueID( _uniqueID ),

       m_registeredAt( _registeredAt )

{

}

//-----------------------------------------------------------------------------

Order::~Order ()

{

   std::for_each(

       m_items.begin(),

       m_items.end(),

       boost::checked_deleter< Item >()

   );

}

//-----------------------------------------------------------------------------

Item &

Order::newItem ( Product const & _product, unsigned int _quantity )

{

   Item * pNewItem = new Item( _product, _quantity );

   m_items.push_back( pNewItem );

   return * pNewItem;

}

//-----------------------------------------------------------------------------

void 

Order::removeItem ( Item & _item )

{

   Items::iterator it = std::find( m_items.begin(), m_items.end(), & _item );

   if ( it == m_items.end() )

       throw std::exception();

   m_items.erase( it );

}

//-----------------------------------------------------------------------------

Money 

Order::getCost () const

{

   Money totalCost = Money();

   

   Items::const_iterator it = m_items.begin();

   while ( it != m_items.end() )

   {

       const Item * pItem = * it;

       totalCost = totalCost + pItem->getCost();

       ++ it;

}

return totalCost;

}

//-----------------------------------------------------------------------------

shop.hpp

#ifndef _SHOP_HPP_

#define _SHOP_HPP_

//-----------------------------------------------------------------------------

#include <string>

#include <vector>

#include <map>

#include <memory>

//-----------------------------------------------------------------------------

class Product;

class Order;

class Money;

//-----------------------------------------------------------------------------

class Shop

{

//-------------------------

public:

//-------------------------

   Shop ( const std::string &_title );

   ~Shop ();

//-------------------------

   const std::string & getTitle () const;

//-------------------------

   Product const & addProduct (

       const std::string & _productName,

       const std::string & _description,

       const Money & _initialPrice

   );

   void dropProduct ( const std::string & _name );

   unsigned int getProductsCount () const;

   Product const * findProduct ( const std::string & _name ) const;

   class ProductIterator

   {

   public:

       virtual bool hasNext () const = 0;

       virtual Product const & getProduct () const = 0;

       virtual void next () = 0;

   };

   std::auto_ptr< ProductIterator > browseProducts () const;

   

//-------------------------

   unsigned int getOrdersCount () const;

   const Order & getOrder ( unsigned int _orderIndex ) const;

   Order & newOrder ();

//-------------------------

private:

//-------------------------

   const std::string m_title;

   typedef std::map< std::string, Product * > ProductDescriptions;

   ProductDescriptions m_products;

   std::vector< Order * > m_orders;

//-------------------------

};

//-----------------------------------------------------------------------------

inline

const std::string &

Shop::getTitle () const

{

   return m_title;

}

//-----------------------------------------------------------------------------

   

inline

unsigned int 

Shop::getProductsCount () const

{

   return m_products.size();

}

//-----------------------------------------------------------------------------

inline

unsigned int 

Shop::getOrdersCount () const

{

   return m_orders.size();

}

//-----------------------------------------------------------------------------

inline

const Order &

Shop::getOrder ( unsigned int _orderIndex ) const

{

   return *( m_orders.at( _orderIndex ) );

}

//-----------------------------------------------------------------------------

#endif //  _SHOP_HPP_

shop.cpp

//-----------------------------------------------------------------------------

#include "shop.hpp"

#include "order.hpp"

#include "product.hpp"

#include <ctime>

#include <algorithm>

#include <exception>

#include <boost/checked_delete.hpp>

//-----------------------------------------------------------------------------

Shop::Shop ( const std::string & _title )

   :    m_title( _title )

{

}

//-----------------------------------------------------------------------------

Shop::~Shop ()

{

   std::for_each(

       m_orders.begin(), 

       m_orders.end(), 

       boost::checked_deleter< Order >()

   );

   std::for_each(

       m_products.begin(), 

       m_products.end(), 

       std::compose1(

           boost::checked_deleter< Product >(),

           std::select2nd< ProductDescriptions::value_type >()

       )

   );

}

//-----------------------------------------------------------------------------

Order &

Shop::newOrder ()

{

   Order * pNewOrder = new Order( getOrdersCount(), time( NULL ) );

   m_orders.push_back( pNewOrder );

   return * pNewOrder;

}

//-----------------------------------------------------------------------------

Product const &

Shop::addProduct (

   const std::string & _productName,

   const std::string & _description,

   const Money & _initialPrice

)

{

   if ( findProduct( _productName ) )

       throw std::exception();

Product * pProduct = new Product(

       m_products.size(), /* id */

       _productName,

       _description,

       _initialPrice

   );

   m_products.insert(

       std::make_pair(

           pProduct->getName(),

           pProduct

       )

   );

   return * pProduct;

}

//-----------------------------------------------------------------------------

void 

Shop::dropProduct ( const std::string & _name )

{

   ProductDescriptions::iterator it = m_products.find( _name );

   if ( it != m_products.end() )

   {

       Product * pProduct = it->second;

       m_products.erase( it );

       delete pProduct;

   }

   else

       throw std::exception();

}

//-----------------------------------------------------------------------------

Product const *

Shop::findProduct ( const std::string & _name ) const

{

   ProductDescriptions::const_iterator it = m_products.find( _name );

   if ( it == m_products.end() )

       return NULL;

   return it->second;

}

//-----------------------------------------------------------------------------

std::auto_ptr< Shop::ProductIterator >

Shop::browseProducts () const

{

   class ProductIteratorImpl

       :    public ProductIterator

   {

   //-----------------------

   public:

   //-----------------------

       ProductIteratorImpl ( ProductDescriptions const & _descriptions )

           :    m_descriptions( _descriptions ),

                m_it( _descriptions.begin() )

       {

       }

               

   //-----------------------

       virtual bool hasNext () const

       {

           return m_it != m_descriptions.end();

       }

   //-----------------------

       virtual Product const & getProduct () const

       {

           return *( m_it->second );

       }

   //-----------------------

       virtual void next ()

       {

           ++ m_it;

       }

   //-----------------------

   private:

   //-----------------------

       ProductDescriptions const & m_descriptions;

       ProductDescriptions::const_iterator m_it;

   //-----------------------

   };

   return std::auto_ptr< ProductIterator >(

       new ProductIteratorImpl( m_products )

);

}

//-----------------------------------------------------------------------------


Пример тестовой программы

Использование рассмотренной выше упрошенной объектной модели магазина может быть продемонстрировано при помощи тестовой программы, которая:

  1.  Активизирует сценарий использования магазина.
  2.  Проверяет ожидания от состояния основных объектов модели после тестового воздействия.
  3.  Распечатывает содержимое объектной модели на консоли.

test.cpp

//-----------------------------------------------------------------------------

#include "shop.hpp"

#include "order.hpp"

#include "item.hpp"

#include "product.hpp"

#include "money.hpp"

#include <cassert>

#include <cstdio>

//-----------------------------------------------------------------------------

void showShopStats ( const Shop & _shop )

{

   printf( "Shop \"%s\" has %d products:\n",

_shop.getTitle().c_str(),

_shop.getProductsCount()

);

   

   std::auto_ptr< Shop::ProductIterator > productIt = _shop.browseProducts();

   while ( productIt->hasNext() )

   {

       Product const & product = productIt->getProduct();

       printf( " - [%d] \"%s\", desription: \"%s\", price: %s\n", 

               product.getUniqueID(), 

               product.getName().c_str(), 

               product.getDescription().c_str(), 

               product.getCurrentPrice().toString().c_str()

       );

       productIt->next();

   }

   putchar( '\n' );

   unsigned int nOrders = _shop.getOrdersCount();

   printf( "Totally there were %d order(s) registered\n",  nOrders );

   putchar( '\n' );

   for ( unsigned int i = 0; i < nOrders; i++ )

   {

       const Order & order = _shop.getOrder( i );

       printf( "Order %d contains %d items with total cost of %s:\n",

               order.getUniqueID(),

               order.getItemsCount(),

               order.getCost().toString().c_str()

);

       unsigned int nItems = order.getItemsCount();

       for ( unsigned int k = 0; k < nItems; k++ )

       {

           const Item & item = order.getItem( k );

           printf( "  Product = '%s', Quantity = %d, Price = %s, Cost = %s\n",

                   item.getProduct().getName().c_str(),

                   item.getQuantity(),

                   item.getPrice().toString().c_str(),

                   item.getCost().toString().c_str() );

       }

       putchar( '\n' );

   }

   putchar( '\n' );

}

//-----------------------------------------------------------------------------

void main ()

{

   /////

   const char * SHOP_TITLE = "MyShop";

   Shop shop( SHOP_TITLE );

   /////

   assert( shop.getTitle() == SHOP_TITLE );

   assert( shop.getOrdersCount() == 0 );

   assert( shop.getProductsCount() == 0 );

   /////

   Product const & batteries = shop.addProduct(

       "Batteries", 

       "A pack with 4 batteries", 

       Money::fromString( "12.00" )

   );

   Product const & dvdDisk = shop.addProduct(

       "DVD disk",  

       "A blank DVD disk for recording", 

       Money::fromString( "3.00" )

   );

   /////

   assert( shop.getProductsCount() == 2 );

   assert( shop.findProduct( "Batteries" ) == & batteries );

   assert( shop.findProduct( "DVD disk" ) == & dvdDisk );

   assert( shop.findProduct( "other-product" ) == NULL );

   /////

   Order & order = shop.newOrder();

   order.newItem( batteries, 1 );

   order.newItem( dvdDisk, 3 );

   /////

   assert( order.getCost().toString() == "21.00" );

   

   assert( order.getItemsCount() == 2 );

   

   assert( order.getItem( 0 ).getQuantity() == 1 );

   assert( order.getItem( 0 ).getCost() == batteries.getCurrentPrice() );

   assert( order.getItem( 1 ).getQuantity() == 3 );

   assert( order.getItem( 1 ).getCost() == ( dvdDisk.getCurrentPrice() *  3 ) );

   /////

   showShopStats( shop );

}

//-----------------------------------------------------------------------------

Процедура защиты лабораторной работы:

  •  подготовить отчет в печатном виде ( один экземпляр на бригаду );
  •  ответить на вопросы преподавателя по ходу выполнения работы, а также на дополнительные теоретические вопросы по теме работы;
  •  студенты, не защитившие данную лабораторную работу, не допускаются к дальнейшим лабораторным работам и сдаче курсового проекта.



1. Деление живой природы на царства
2. Контрольная работа- Понятие и принципы государственного устройства РФ
3. тематике часто встречаются последовательности чисел в которых каждый следующий член выражается через преды
4. жави а також розвиток головних галузей права
5. статья посвящена только внебольничной П
6. Лицензирование предпринимательской деятельности
7. .1. Понятие уставного капитала
8. на тему- Связь поколений подготовительная группа
9. Введение Одной из самых сложных и интересных тем в аудите финансовой отчетности является аудиторская выбор
10. Концепция В
11. Реферат- Вакуумные насос
12. Лабораторная работа 3
13. Анализ существующих информационно-поисковых систем
14. Биокальций для улучшения мозговой деятельности содержит кальций выделенный из скелетов сельскохозяйств.html
15. Назови ласково- колбаса ~ колбаска компот ~ котлета ~
16. нового года С древних времен Новый год главный праздник у большинства народов земного шара.
17. Страховое возмещение
18. Западничество и славянофильство и выбор пути развития русской культуры
19. Тульский государственный университет Политехнический институт Кафедра
20. г