`
kmplayer
  • 浏览: 498499 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

句柄的使用实例

阅读更多
1,这个实例采用了使用计数策略.

2,实例代码:
#include <iostream>
#include <string>
#include <set>
#include <map>
#include <utility>
#include <cstddef>
#include <stdexcept>
#include <algorithm>
using namespace std;

class Item_base
{
friend istream& operator>>(istream&, Item_base&);
friend ostream& operator<<(ostream&, const Item_base&);
public:
    virtual Item_base* clone() const
    {
        return new Item_base(*this);
    }
public:
    Item_base(const string &book = "",double sales_price = 0.0):
            isbn(book), price(sales_price) { }

    string book() const //接口和实现
    {
        return isbn;
    }

    virtual double net_price(size_t n) const //接口和缺省
    {
        return n * price;
    }

    virtual ~Item_base() { } //基类必须的虚析构
private:
    string isbn;
protected:
    double price;
};


class Bulk_item : public Item_base //一个继承类
{
public:
    Bulk_item* clone() const //配合计数句柄
    {
        return new Bulk_item(*this);
    }

    Bulk_item(): min_qty(0), discount(0.0) { }

    Bulk_item(const string& book, double sales_price, size_t qty = 0, double disc_rate = 0.0):
            Item_base(book, sales_price),min_qty(qty), discount(disc_rate) { }

    double net_price(size_t) const; //继承的接口
private:
    size_t min_qty;
    double discount;
};
double Bulk_item::net_price(size_t cnt) const
{
    if (cnt >= min_qty)
        return cnt * (1 - discount) * price;
    else
        return cnt * price;
}

class Lim_item : public Item_base //第二个继承类
{
public:
    Lim_item* clone() const
    {
        return new Lim_item(*this);
    }

    Lim_item(const string& book = "", double sales_price = 0.0, size_t qty = 0, double disc_rate = 0.0):
            Item_base(book, sales_price), max_qty(qty), discount(disc_rate) { }

    double net_price(size_t) const;
private:
    size_t max_qty;
    double discount;
};
double Lim_item::net_price(size_t cnt) const
{
    size_t discounted = min(cnt, max_qty);
    size_t undiscounted = cnt - discounted;
    return discounted * (1 - discount) * price + undiscounted * price;
}

class Sales_item  //计数句柄类
{
public:
    friend class Basket;

    Sales_item() : p(NULL), use(new size_t(1)) {}

    Sales_item( const Item_base& item) : p(item.clone()), use(new size_t(1)) {}

    Sales_item(const Sales_item& s) : p(s.p), use(s.use)
    {
        (*use)++;
    }

    Sales_item& operator=(const Sales_item& rhs)
    {
        if( &rhs == this)
            return *this;
        (*rhs.use)++;
        decr_use();
        p = rhs.p;
        use = rhs.use;
        return *this;
    }

    ~Sales_item()
    {
        decr_use();
    }

    const Item_base* operator->() const
    {
        if (p)
            return p;
        else
            throw logic_error("unbound Sales_item");
    }

    const Item_base& operator*() const
    {
        if (p)
            return *p;
        else
            throw logic_error("unbound Sales_item");
    }

private:
    Item_base* p;
    size_t* use;
    void decr_use()
    {
        if( --(*use) == 0)
        {
            delete p;
            delete use;
        }
    }
};

inline bool compare(const Sales_item &lhs, const Sales_item &rhs) //比较函数,构造map容器.
{
    return lhs->book() < rhs->book();
}

class Basket //一个操作类
{
    typedef bool (*Comp)(const Sales_item&, const Sales_item&);
public:
    typedef multiset<Sales_item, Comp> set_type;
    typedef set_type::size_type size_type;
    typedef set_type::const_iterator const_iter;

    Basket(): items(&compare) { }  // 初始化

    void add_item(const Sales_item &item)
    {
        items.insert(item);
    }

    size_type size(const Sales_item &i) const
    {
        return items.count(i);
    }

    double total() const;  // sum of net prices for all items in the basket

private:
    std::multiset<Sales_item, Comp> items;
};

double Basket::total() const
{
    double sum = 0.0;

    for (const_iter iter = items.begin(); iter != items.end(); iter = items.upper_bound(*iter))
    {
        int num = items.count(*iter);
        double value = (*iter) -> net_price(num);
        cout << "ISBN: " << (*iter) -> book()
             << "\tnumber sold: " << num
             << "\ttotal price: " << value
             << endl;
        sum += value;
    }
    return sum;
}

int main()
{
	Sales_item item1(Item_base("123", 45));
	Sales_item item2(Bulk_item("345", 45, 3, .15));
	Sales_item item3(Bulk_item("678", 55, 5, .25));
	Sales_item item4(Lim_item("abc", 35, 2, .10));
	Sales_item item5(Item_base("def", 35));

	Basket sale;
	cout << "added first item" << endl;
	sale.add_item(item1);
	sale.add_item(item1);
	sale.add_item(item1);
	sale.add_item(item1);
	sale.add_item(item2);
	sale.add_item(item2);
	sale.add_item(item2);
	sale.add_item(item2);
	sale.add_item(item2);
	sale.add_item(item2);
	sale.add_item(item2);
	sale.add_item(item2);
	sale.add_item(item3);
	sale.add_item(item3);
	sale.add_item(item3);
	sale.add_item(item3);
	sale.add_item(item3);
	sale.add_item(item3);
	sale.add_item(item3);
	sale.add_item(item3);
	sale.add_item(item4);
	sale.add_item(item4);
	sale.add_item(item4);
	sale.add_item(item4);
	sale.add_item(item4);
	sale.add_item(item4);
	sale.add_item(item5);
	sale.add_item(item5);
    cout << "added last item" << endl;
	cout << sale.total() << endl;
    return 0;
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics