C++ Primer(第5版) 练习 15.30
练习 15.30 编写你自己的Basket类,用它计算上一个练习中交易记录的总价格。
环境:Linux Ubuntu(云服务器)
工具:vim
代码块:
# include <iostream>
# include <vector>
# include <memory>
# include <set>
using namespace std;
class Quote {
public :
Quote ( ) = default ;
Quote ( const std:: string & book, double sales_price) : bookNo ( book) , price ( sales_price) { }
std:: string isbn ( ) const { return bookNo; }
virtual double net_price ( std:: size_t n) const { return n * price; }
virtual ~ Quote ( ) = default ;
virtual Quote* clone ( ) const & { return new Quote ( * this ) ; }
virtual Quote* clone ( ) && { return new Quote ( std:: move ( * this ) ) ; }
private :
std:: string bookNo;
protected :
double price = 0.0 ;
} ;
class Disc_quote : public Quote {
public :
Disc_quote ( ) = default ;
Disc_quote ( const std:: string & book, double price, std:: size_t qty, double disc) : Quote ( book, price) , quantity ( qty) , discount ( disc) { }
double net_price ( std:: size_t) const = 0 ;
protected :
std:: size_t quantity = 0 ;
double discount = 0.0 ;
} ;
class Bulk_quote : public Disc_quote {
public :
Bulk_quote ( ) = default ;
Bulk_quote ( const std:: string& book, double price, std:: size_t qty, double disc) : Disc_quote ( book, price, qty, disc) { }
double net_price ( std:: size_t) const override ;
Bulk_quote* clone ( ) const & { return new Bulk_quote ( * this ) ; }
Bulk_quote* clone ( ) && { return new Bulk_quote ( std:: move ( * this ) ) ; }
} ;
double Bulk_quote :: net_price ( size_t cnt) const {
if ( cnt >= quantity) {
return cnt * ( 1 - discount) * price;
}
else {
return cnt * price;
}
}
double print_total ( ostream & os, const Quote & item, size_t n) {
double ret = item. net_price ( n) ;
os<< "ISBN: " << item. isbn ( ) << " # sold: " << n<< " total due: " << ret<< endl;
return ret;
}
class Basket {
public :
void add_item ( const Quote& sale) {
items. insert ( std:: shared_ptr < Quote> ( sale. clone ( ) ) ) ;
}
void add_item ( Quote&& sale) {
items. insert ( std:: shared_ptr < Quote> ( std:: move ( sale) . clone ( ) ) ) ;
}
double total_receipt ( std:: ostream& ) const ;
private :
static bool compare ( const std:: shared_ptr< Quote> & lhs, const std:: shared_ptr< Quote> & rhs) {
return lhs-> isbn ( ) < rhs-> isbn ( ) ;
}
std:: multiset< std:: shared_ptr< Quote> , decltype ( compare) * > items{ compare} ;
} ;
double Basket :: total_receipt ( ostream & os) const {
double 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 Sales: " << sum<< endl;
return sum;
}
int main ( ) {
Basket obj;
obj. add_item ( Quote ( "0-101-13456-X" , 10 ) ) ;
obj. add_item ( Bulk_quote ( "0-102-34567-Y" , 15 , 20 , 0.5 ) ) ;
obj. add_item ( Bulk_quote ( "0-103-32467-X" , 5 , 30 , 0.5 ) ) ;
obj. total_receipt ( cout) ;
return 0 ;
}
运行结果显示如下: