句柄类与继承

 1 /**
 2  * C++ 面向对象编程的一个颇具讽刺意味的地方是:不能使用对象支持面向对象编程,
 3  *相反,必须使用指针或引用,例如:
 4  */
 5 void get_prices(Item_base object, const Item_base *pointer, const Item_base &reference)
 6 {
 7     //下边的两个调用在运行时进行动态绑定
 8     cout << pointer->net_price(1) << endl;
 9     cout << reference.net_price(1) << endl;
10     
11     //下边的调用无论是基类还是子类都调用基类的成员函数
12     cout << object.net_price(1) << endl;
13 }

 

指针型句柄练习:

 1 //Basket.h
 2 #ifndef BASKET_H
 3 #define BASKET_H
 4 
 5 #include "Sales_item.h"
 6 #include <set>
 7 
 8 inline bool compare(const Sales_item &lhs, const Sales_item &rhs)
 9 {
10     return lhs->book() < rhs->book();
11 }
12 
13 class Basket
14 {
15     //用于multiset元素排序的比较函数的类型---Comp是函数指针,指向的函数带有两个Sales_item类型的参数
16     typedef bool (*Comp)(const Sales_item&, const Sales_item&);
17 public:
18     //multiset成员的类型
19     typedef std::multiset<Sales_item, Comp> set_type;
20     //类型别名
21     typedef set_type::size_type size_type;
22     typedef set_type::const_iterator const_itor;
23     
24     Basket() : items(compare) {} //初始化比较器
25     
26     void add_item(const Sales_item &item)
27     {
28         items.insert(item);
29     }
30     
31     size_type size(const Sales_item &i) const
32     {
33         return items.count(i);
34     }
35     
36     double total() const;  // 返回购物篮中所有物品的总价格
37 private:
38     std::multiset<Sales_item, Comp> items;
39 };
40 
41 #endif
 1 //定义compare函数和Basket类的实现文件如下:
 2 //Basket.cpp
 3 
 4 #include "Basket.h"
 5 
 6 double Basket::total() const
 7 {
 8     double sum = 0.0;    // holds the running total
 9     
10     // 找到具有相同 ISBN 的每一组物品,根据其总数计算价格,itor指向 ISBN 相同的每一组中的第一个元素
11     //    upper_bound 指向具有不同 ISBN 的下一个元素
12     for(const_itor itor = items.begin(); itor != items.end(); itor = items.upper_bound(*itor))
13     {
14         sum += (*itor)->net_price(items.count(*itor));
15     }
16     return sum;
17 }
 1 // 使用 Basket 类管理销售
 2 #include "Basket.h"
 3 #include "Sales_item.h"
 4 #include <iostream>
 5 using namespace std;
 6 
 7 int main()
 8 {
 9     Basket basket;
10     Sales_item item1(Bulk_item("7-115-14554-7", 99, 20, 0.2));
11     Sales_item item2(Item_base("7-115-14554-8", 39));
12     Sales_item item3(Lds_item("7-115-14554-9", 50, 200, 0.2));
13     Sales_item item4(Bulk_item("7-115-14554-7", 99, 20, 0.2));
14     
15     basket.add_item(item1);
16     basket.add_item(item2);
17     basket.add_item(item3);
18     basket.add_item(item4);
19     
20     cout << basket.total() << endl;
21     
22     return 0;
23 }
  1 // Item.h
  2 //  定义Item_base类层次的头文件
  3 
  4 #ifndef ITEM_H
  5 #define ITEM_H
  6 #include <string>
  7 
  8 using namespace std;
  9 
 10 // 不使用折扣策略的基类
 11 class Item_base
 12 {
 13 public:
 14     Item_base(const std::string &book = "", double sales_price = 0.0) :
 15         isbn(book), price(sales_price){}
 16     
 17     std::string book() const
 18     {
 19         return isbn;
 20     }
 21     // 返回特定购书量的总价格---派生类将重载该函数以应用不同的折扣策略
 22     virtual double net_price(size_t n) const
 23     {
 24         return n * price;
 25     }
 26     
 27     virtual Item_base* clone() const
 28     {
 29         return new Item_base(*this);
 30     }
 31     
 32     virtual ~Item_base() {}
 33 private:
 34     std::string isbn;
 35 protected:
 36     double price;
 37 };
 38 
 39 //保存折扣率和可实行折扣策略的数量---派生类将使用这些数据实行定价策略
 40 class Disc_item : public Item_base
 41 {
 42 public:
 43     Disc_item(const std::string& book = "", double sales_price = 0.0,
 44               size_t qty = 0, double disc_rate = 0.0) :
 45                    Item_base(book, sales_price), quantity(qty), discount(disc_rate) {}
 46                    
 47     double net_price(size_t) const = 0; //纯虚函数---该函数为后代类型提供了可以覆盖的接口,
 48                 //但是这个类中的版本决不会调用,重要的是,用户将不能创建Disc_item类型的对象
 49     
 50     std::pair<size_t, double> discount_policy() const
 51     {
 52         return std::make_pair(quantity, discount);
 53     }
 54 protected:
 55     size_t quantity;  //可实行折扣策略的购买量
 56     double discount;  // 折扣率
 57 };
 58 
 59 // 批量购买折扣类
 60 class Bulk_item : public Disc_item
 61 {
 62 public:
 63     Bulk_item(const std::string& book = "", double sales_price = 0.0,
 64               size_t qty = 0, double disc_rate = 0.0) :
 65                     Disc_item(book, sales_price, qty, disc_rate) {}
 66                     
 67     // 重定义基类版本以实行批量购买折扣策略:若购书量高于下限,则使用折扣价格
 68     double net_price(size_t cnt) const
 69     {
 70         if(cnt >= quantity)
 71             return cnt * (1-discount) * price;
 72         else
 73             return cnt * price;
 74     }
 75     
 76     virtual Bulk_item* clone() const
 77     {
 78         return new Bulk_item(*this);
 79     }
 80 };
 81 
 82 //有限折扣类
 83 class Lds_item : public Disc_item
 84 {
 85 public:
 86     // 构造函数
 87     Lds_item(const std::string& book = "", double sales_price = 0.0,
 88               size_t qty = 0, double disc_rate = 0.0) :
 89                     Disc_item(book, sales_price, qty, disc_rate) {}
 90                     
 91     // 重定义基类版本以实现有限折扣策略---对低于上限的购书量使用折扣价格
 92     double net_price(size_t cnt) const
 93     {
 94         if(cnt <= quantity)
 95             return cnt * (1 - discount) * price;
 96         else
 97             return cnt * price - quantity * discount * price;
 98     }
 99     
100     virtual Lds_item* clone() const
101     {
102         return new Lds_item(*this);
103     }
104 };
105 
106 #endif
 1 // Sales_item.h---Sales_item 类的头文件
 2 
 3 #ifndef SALESITEM_H
 4 #define SALESITEM_H
 5 #include "Item.h"
 6 
 7 // 用于Item_base 层次的使用计数式句柄类
 8 class Sales_item
 9 {
10 public:
11     // 默认构造函数:创建未绑定的句柄
12     Sales_item() : p(0), use(new std::size_t(1)) { }
13     
14     // 将创建绑定到Item_base对象副本的句柄
15     Sales_item(const Item_base& item) : p(item.clone()), use(new std::size_t(1)) { }
16     
17     // 复制控制成员管理使用计数和指针
18     Sales_item(const Sales_item &i) : p(i.p), use(i.use) { ++*use; };
19     ~Sales_item() { decr_use(); }
20     Sales_item& operator = (const Sales_item);
21     
22     //成员访问操作符
23     const Item_base *operator->() const
24     {
25         if(p)
26             return p;
27         else
28             throw std::logic_error("unbound Sales_item");
29     }
30     const Item_base &operator*() const
31     {
32         if(p)
33             return *p;
34         else
35             throw std::logic_error("unbound Sales_item");
36     }
37 private:
38     Item_base *p;    //指向共享Item_base对象的指针
39     std::size_t *use;  //指向共享使用计数的指针
40     
41     // 为析构函数和赋值操作符所用的辅助函数
42     void decr_use()
43     {
44         if(--*use == 0)
45         {
46             delete p;
47             delete use;
48         }
49     }
50 };
51 #endif
 1 // Sales_item.cpp---Sales_item 类的实现文件(源文件)
 2 #include "Sales_item.h"
 3 
 4 Sales_item& Sales_item::operator = (const Sales_item &rhs)
 5 {
 6     ++*use;
 7     decr_use();
 8     p = rhs.p;
 9     use = rhs.use;
10     return *this;
11 }
原文地址:https://www.cnblogs.com/dongsheng/p/3342073.html