C++ primer5 15.3/15.5/15.15/15.21-22/15.28-29/15.30/15.35

本文档展示了C++代码实现的书籍销售系统,包括基类Quote、Bulk_quote派生类以及Disc_quote抽象基类。系统支持不同折扣策略,如Bulk_quote类根据购买量提供打折。此外,还定义了一个Basket类来计算购物车中所有书籍的总价。最后,定义了Query类和Query_base类,用于实现文本查询系统,支持多种查询操作。
摘要由CSDN通过智能技术生成

15.3 Quote销售书籍基类

#ifndef QUOTE_H
#define QUOTE_H

#include <string>
#include <iostream>
#include <vector>
using namespace std;
class Quote//销售书籍基类
{
public:
    Quote() = default;
    Quote(string const &b, double p) : bookNo(b), price(p) {}

    string isbn() const { return bookNo; } //书籍编号
    virtual double net_price(size_t n) const { return n * price; }//总售价,派生类重写
    virtual void  debug() const; //显示每个类的数据成员
    virtual ~Quote() = default;//基类需要是虚析构函数
private:
    string bookNo; //书籍编号,派生类和其它类只能通过isbn()函数访问
protected:
    double price = 0.0;//单价,派生类可以直接访问
};

void Quote::debug() const
{
    std::cout << "data members of this class:\n"
              << "bookNo= " <<this->bookNo << " "
              << "price= " <<this->price<< " ";
}
#endif

15.5 Bulk_quote派生类-打折销售

#ifndef BULK_QUOTE_H
#define BULK_QUOTE_H

#include <string>
#include <iostream>
#include <vector>
#include <quote.h> //包含基类的头文件
using namespace std;
class Bulk_quote : public Quote //销售书籍派生类
{
public:
    Bulk_quote() = default;
    Bulk_quote(string const &b, double p, size_t q, double disc) : Quote(b, p), min_qty(q), discount(disc) {}

    double net_price(size_t n) const override;//总售价,派生类重写
    void  debug() const override;

private:
    size_t min_qty = 0; //适用折扣政策的最低购买量
    double discount = 0.0;//折扣额
};
double Bulk_quote::net_price(size_t n) const
{
    return n * price * ( n >= min_qty ? 1-discount : 1); //超过最低购买量即可打折(1-discount)<1
}
void Bulk_quote::debug() const
{
	Quote::debug();//直接调用基类函数
    std::cout << "min_qty= " << this->min_qty << " "
              << "discount= " << this->discount<< " ";
}
#endif

15.15 定义支持不同折扣策略的通用Disc_quote抽象基类和某种特定策略的Bulk_quote类

#ifndef DISC_QUOTE_H
#define DISC_QUOTE_H
using namespace std;
#include "quote.h"
class Disc_quote : public Quote
{
public:
   Disc_quote();
   Disc_quote(const string &b, double p, size_t q, double d) : Quote(b, p), quantity(q), discount(d) { }

   virtual double net_price(size_t n) const override = 0;
protected:
   size_t quantity;
   double discount;
};
#endif
#ifndef BULK_QUOTE_H
#define BULK_QUOTE_H

#include <string>
#include <iostream>
#include <vector>
#include <disc_quote.h>
using namespace std;
class Bulk_quote : public Disc_quote //销售书籍派生类
{
public:
    Bulk_quote() = default;
    Bulk_quote(string const &b, double p, size_t q, double disc) : Disc_quote(b, p, q, disc) {}

    double net_price(size_t n) const override;//总售价,派生类重写
    void debug() const override;
};
double Bulk_quote::net_price(size_t n) const
{
    return n * price * ( n >= quantity ? 1-discount : 1); //超过最低购买量即可打折(1-discount)<1
}
void Bulk_quote::debug() const
{
	Quote::debug(); //直接调用基类函数
    std::cout //<< "data members of this class:\n"
              << "min_qty= " << quantity << " "
              << "discount= " << discount<< " ";
}
#endif

15.21-22 图形继承体系

#include <utility>
#include <string>
using namespace std;
class Shape //形状基类
{
public:
   typedef pair<double, double> Coordinate;
   Shape() = default;
   Shape(const string& n) : name(n) { }
   virtual double area() const = 0;     //周长计算
   virtual double perimeter() const = 0;//面积计算
   virtual ~Shape() = default;
private:
   string name;
};
class Rectangle : public Shape //形状类派生出矩形类
{
public:
   Rectangle() = default;
   Rectangle(const std::string& n,
             const Coordinate& a, const Coordinate& b,
             const Coordinate& c, const Coordinate& d) :
        Shape(n), a(a), b(b), c(c), d(d) { }
   ~Rectangle() = default;
protected:
   Coordinate a; //四个顶点(受保护成员)
   Coordinate b;
   Coordinate c;
   Coordinate d;
};
class Square : public Rectangle //矩形类派生出正方形类
{
public:
    Square() = default;
    Square(const std::string& n,
           const Coordinate& a, const Coordinate& b,
           const Coordinate& c, const Coordinate& d) :
        Rectangle(n, a, b, c, d) { }
    ~Square() = default;
};

15.28-29 定义一个存放Quote对象的vector,将Bulk_qoute传入其中,计算vector中所有元素总的net_price。在运行一次,这次传入Quote对象的shared_ptr。

#include <vector>
#include <iostream>
#include <algorithm>
#include "Quote.h"
using namespace std;
 
int main(int argc, char**argv)
{
	vector<Quote> vec1;
	bulk_quote b1(string("C++ Primer I"),128,10,0.5);
	bulk_quote b2(string("C++ Primer II"),118,8,0.6);
	bulk_quote b3(string("C++ Primer III"),108,12,0.4);
	bulk_quote b4(string("C++ Primer IV"),138,4,0.3);
	vec1.push_back(b1);
	vec1.push_back(b2);
	vec1.push_back(b3);
	vec1.push_back(b4);
	double Sum_of_net_price1 = 0;
	for(int i = 0; i < vec1.size(); ++i)
	{
		Sum_of_net_price1 += vec1[i].net_price(20);
		cout<<Sum_of_net_price1<<endl;
	}
	cout<<"The total net price is:"<<Sum_of_net_price1<<endl;
 
	vector<shared_ptr<Quote>> vec2;
	vec2.push_back(make_shared<bulk_quote>(b1));
	vec2.push_back(make_shared<bulk_quote>(b2));
	vec2.push_back(make_shared<bulk_quote>(b3));
	vec2.push_back(make_shared<bulk_quote>(b4));
	double Sum_of_net_price2 = 0;
	for(int i = 0; i < vec2.size(); ++i)
	{
		Sum_of_net_price2 += vec2[i]->net_price(20);
		cout<<Sum_of_net_price2<<endl;
	}
	cout<<"The total net price is:"<<Sum_of_net_price2<<endl;
 
	return 0;
}

15.30 编写Basket类,计算交易记录的总价格

#ifndef BASKET_H
#define BASKET_H
#include "quote.h"
#include "bulk_quote.h"
using namespace std;
class Basket
{
public:
   Basket() = default; //显式告诉编译器去生成默认构造函数
   void add_item(const Quote &sale) { items.insert(shared_ptr<Quote>(sale.clone())); } //拷贝
   void add_item(Quote &&sale) { items.insert(shared_ptr<Quote>(std::move(sale).clone())); }//移动
   inline double total_receipt(std::ostream&) const;
private:
   static bool compare(const shared_ptr<Quote> &lhs, const shared_ptr<Quote> &rhs) 
   {
        return lhs->isbn() < rhs->isbn();
   }
};
inline double Basket::total_receipt(std::ostream &os) const 
{
    auto sum = 0.0;
    for (auto iter = items.cbegin(); iter != items.cend(); iter = items.upper_bound(*iter)) 
    {
        sum += print_total(os, **iter, items.count(*iter));
    }
    os << "Total Sale: " << sum << std::endl;
    return sum;
}
#endif

15.35 实现Query类和Query_base类,其中需要定义rep而无须定义eval

#ifndef QUERY_H
#define QUERY_H
#include <string>
#include <vector>
#include <set>
#include <map>
using namespace std;
class TextQuery;
class QueryResult //QueryResult保存查询的结果
{
public:
	typedef vector<string>::size_type line_no;//保存出现的行号,使用类型别名
	friend ostream& operator<<(ostream&, const QueryResult&);//输出查询结果
public:
	QueryResult(const string& s, shared_ptr<std::set<line_no>> set,shared_ptr<vector<string>> v)
		               : word(s), nos(set), input(v) { }
private:
	string word;//查询的单词
	shared_ptr<std::set<line_no>> nos;//用set保存出现的行号,自动排序
	shared_ptr<vector<string>> input;//输入文件vector的指针
};

class TextQuery //TextQuery接受输入文件,并保存,生成map
{
public:
	/*using line_no = vector<string>::size_type;//C++11新标准,可以使用typedef代替*/
	typedef vector<string>::size_type line_no;
	TextQuery(ifstream&);//接受输入文件的构造函数
	QueryResult query(const string&) const;//具体的查询函数
private:
	shared_ptr<vector<string>> input;//保存输入的vector的智能指针
	map<string, shared_ptr<set<line_no>>> result;//map保存单词出现的行和列
};

class Query_base //抽象基类Query_base,用于派生
{
	friend class Query;
private:
	//纯虚函数,返回与当前Query匹配的QueryResult
	/*virtual QueryResult eval(const TextQuery&) const = 0;*/
	virtual string rep() const = 0;//纯虚函数,保存用于查询的string
protected:
	/*using line_no = vector<string>::size_type;//C++11新标准,可以使用typedef代替*/
	typedef vector<string>::size_type line_no;
	virtual ~Query_base() /*= default*/;//C++11新标准,不加
};

class Query //查询基类 Query
{   //定义运算符函数
	friend Query operator~(const Query&);
	friend Query operator|(const Query&,const Query&);
	friend Query operator&(const Query&,const Query&);
public:
	Query(const string&s);//新的构造函数,查询单词
	//接口函数
// 	QueryResult eval(const TextQuery &t) const
// 	{
// 		return q->eval(t);//查询结果
// 	}//事先无需定义
	string rep() const
	{
		return q->rep();//查询单词
	}
private:
	Query(shared_ptr<Query_base> query):q(query){} //构造函数,接受一个Query_base的指针
	shared_ptr<Query_base> q; //保存一个指向基类的指针,私有成员
};
 
std::ostream &operator<<(std::ostream &os, const Query query)  
{  
	return os << query.rep();  
} 

class WordQuery:public Query_base //基础查询单词类
{
	//所有成员皆为private,
	friend class Query;//Query需要使用其构造函数
	WordQuery(const string &s):Query_word(s){cout<<"WordQuery"<<endl;}//初始化
 
	QueryResult eval(const TextQuery& t) const
	{
		return t.query(Query_word);
	}//纯虚函数,必须重写
	string rep() const
	{
		return Query_word;
	}//纯虚函数,必须重写
	string Query_word;
};
inline Query::Query(const string &s):q(new WordQuery(s)){cout<<"Query"<<endl;}//程序顺序执行,所用之对象必须进行声明

class NotQuery:public Query_base //NotQuery类,取反的query
{
	friend Query operator~(const Query&);
	NotQuery(const Query&q):query(q){cout<<"NotQuery"<<endl;}//构造函数
 
	string rep()
	{
		return "~("+query.rep()+")";//表示不需要查询的单词
	}
	QueryResult eval(const TextQuery&);
	Query query;
};
// inline Query operator~(const Query&operand)
// {
// 	return shared_ptr<Query_base>(new NotQuery(operand));
// }

class BinaryQuery:public Query_base //BinaryQuery类,一个抽象基类,因为继承了基类的纯虚函数eval()
{
protected:
	BinaryQuery(const Query&l, const Query&r,string s):lhs(l),rhs(r),opSym(s){cout<<"BinaryQuery"<<endl;}//构造函数
	string rep() const
	{	cout<<"Binary_rep"<<endl;//36题
		return "("+lhs.rep()+" "+opSym+" "+rhs.rep()+")";
	}
	Query lhs,rhs;
	string opSym;//运算符的名字
};
 
class AndQuery:public BinaryQuery //AndQuery类,继承自抽象基类BinaryQuery
{
protected:
	friend Query operator&(const Query&,const Query&);//之前定义的运算符
	AndQuery(const Query&left, const Query&right):BinaryQuery(left,right,"&"){cout<<"AndQuery"<<endl;}//构造函数
	//返回查询结果的函数
	QueryResult eval(const TextQuery&);
};
// inline Query operator&(const Query&lhs, const Query&rhs)
// {
// 	return shared_ptr<Query_base>(new AndQuery(lhs,rhs));//在未定义纯虚函数eval()时,为抽象基类,不可实例化
// }
 
class OrQuery:public BinaryQuery //OrQuery类,继承自抽象基类BinaryQuery
{
protected:
	friend Query operator|(const Query&,const Query&);//之前定义的运算符
	OrQuery(const Query&left, const Query&right):BinaryQuery(left,right,"|"){cout<<"OrQuery"<<endl;}//构造函数
	//返回查询结果的函数
	QueryResult eval(const TextQuery&);
};
// inline Query operator|(const Query&lhs, const Query&rhs)
// {
// 	return shared_ptr<Query_base>(new OrQuery(lhs,rhs));
// }
 
#endif QUERY_H
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值