10.8. Implementing Safe Polymorphism
Now that we have an overview of the structure of the
classes we're designing,
Figure 10.23 shows the interfaces for the worker
classes UndatedStockItem and
DatedStockItem.
FIGURE 10.23. Safe polymorphism: The
UndatedStockItem and
DatedStockItem interfaces for the polymorphic version of
StockItem (code\itempi.h)
class UndatedStockItem : public StockItem
UndatedStockItem(std::string Name, short InStock,
short Price, short MinimumStock, short ReorderQuantity,
std::string Distributor, std::string UPC);
virtual bool CheckUPC(std::string UPC);
virtual void DeductSaleFromInventory(short QuantitySold);
virtual short GetInventory();
virtual std::string GetName();
virtual void Reorder(std::ostream& os);
virtual void FormattedDisplay(std::ostream& os);
virtual std::ostream& Write(std::ostream& os);
std::string m_Distributor;
class DatedStockItem : public UndatedStockItem
DatedStockItem(std::string Name, short InStock,
short Price, short MinimumStock, short MinimumReorder,
std::string Distributor, std::string UPC, std::string Expires);
virtual void Reorder(std::ostream& os);
virtual void FormattedDisplay(std::ostream& os);
virtual std::ostream& Write(std::ostream& os);
static std::string Today();
FIGURE 10.24. Safe polymorphism: The implementation of the
UndatedStockItem and
DatedStockItem classes (code\itemp.cpp)
//friend functions of StockItem
ostream& operator << (ostream& os, const StockItem& Item)
return Item.m_Worker->Write(os);
istream& operator >> (istream& is, StockItem& Item)
Item = StockItem(Name, InStock, Price, MinimumStock,
MinimumReorder, Distributor, UPC);
Item = StockItem(Name, InStock, Price, MinimumStock,
MinimumReorder, Distributor, UPC, Expires);
// StockItem member functions
: m_Count(0), m_Worker(new UndatedStockItem)
StockItem::StockItem(const StockItem& Item)
: m_Count(0), m_Worker(Item.m_Worker)
StockItem& StockItem::operator = (const StockItem& Item)
StockItem* temp = m_Worker;
m_Worker = Item.m_Worker;
if (m_Worker->m_Count <= 0)
StockItem::StockItem(string Name, short InStock, // Undated
short Price, short MinimumStock, short MinimumReorder,
string Distributor, string UPC)
m_Worker(new UndatedStockItem(Name, InStock, Price,
MinimumStock, MinimumReorder, Distributor, UPC))
StockItem::StockItem(int)
StockItem::StockItem(string Name, short InStock, // Dated
short Price, short MinimumStock, short MinimumReorder,
string Distributor, string UPC, string Expires)
m_Worker(new DatedStockItem(Name, InStock, Price,
MinimumStock, MinimumReorder, Distributor, UPC, Expires))
bool StockItem::CheckUPC(string UPC)
return m_Worker->CheckUPC(UPC);
short StockItem::GetInventory()
return m_Worker->GetInventory();
void StockItem::DeductSaleFromInventory(short QuantitySold)
m_Worker->DeductSaleFromInventory(QuantitySold);
string StockItem::GetName()
return m_Worker->GetName();
ostream& StockItem::Write(ostream& os)
exit(1); // should never get here
void StockItem::Reorder(ostream& os)
void StockItem::FormattedDisplay(ostream& os)
m_Worker->FormattedDisplay(os);
// UndatedStockItem member functions
UndatedStockItem::UndatedStockItem()
UndatedStockItem::UndatedStockItem(string Name,
short InStock, short Price, short MinimumStock,
short MinimumReorder, string Distributor, string UPC)
m_MinimumStock(MinimumStock),
m_MinimumReorder(MinimumReorder),
m_Distributor(Distributor),
void UndatedStockItem::FormattedDisplay(ostream& os)
os << "Number in stock: ";
os << m_MinimumStock << endl;
os << "Reorder quantity: ";
os << m_MinimumReorder << endl;
os << m_Distributor << endl;
ostream& UndatedStockItem::Write(ostream& os)
os << m_MinimumStock << endl;
os << m_MinimumReorder << endl;
os << m_Distributor << endl;
void UndatedStockItem::Reorder(ostream& os)
if (m_InStock < m_MinimumStock)
ReorderAmount = m_MinimumStock-m_InStock;
if (ReorderAmount < m_MinimumReorder)
ReorderAmount = m_MinimumReorder;
os << "Reorder " << ReorderAmount;
os << " units of " << m_Name << " with UPC ";
os << m_UPC << " from " << m_Distributor << endl;
bool UndatedStockItem::CheckUPC(string UPC)
short UndatedStockItem::GetInventory()
void UndatedStockItem::DeductSaleFromInventory(
m_InStock -= QuantitySold;
string UndatedStockItem::GetName()
// DatedStockItem member functions
DatedStockItem::DatedStockItem(string Name, short InStock,
short Price, short MinimumStock, short MinimumReorder,
string Distributor, string UPC, string Expires)
: UndatedStockItem(Name,InStock,Price,MinimumStock,
MinimumReorder,Distributor,UPC),
ostream& DatedStockItem::Write(ostream& os)
os << m_MinimumStock << endl;
os << m_MinimumReorder << endl;
os << m_Distributor << endl;
void DatedStockItem::FormattedDisplay(ostream& os)
os << "Expiration date: ";
os << "Number in stock: ";
os << m_MinimumStock << endl;
os << "Reorder quantity: ";
os << m_MinimumReorder << endl;
os << m_Distributor << endl;
string DatedStockItem::Today()
stringstream FormatStream;
FormatStream << setfill(`0') << setw(4) << year <<
setw(2) << month << setw(2) << day;
FormatStream >> TodaysDate;
void DatedStockItem::Reorder(ostream& os)
os << "Return " << m_InStock << " units of " << m_Name;
os << " with UPC " << m_UPC;
os << " to " << m_Distributor << endl;
UndatedStockItem::Reorder(os);
Let's start our examination of this new
StockItem class by looking at the implementation of
operator << in
Figure 10.25.
FIGURE 10.25. Safe polymorphism: The implementation of
operator << for a polymorphic