容器与继承
Exercise 15.28:
Define a vector to hold Quote
objects but put Bulk_quote objects into that vector. Compute the total net_price of all the elements in the vector.
Exercise 15.29:
Repeat your program, but this time store shared_ptrs
to objects of type Quote. Explain any discrepancy in the sum generated by the this version and the previous program.
由于前面练习中的vector包含对象,因此不存在多态性在调用虚函数net_price时发生。从本质上讲,对象被推回去的Bulk_quote对象的Quote主题,因此,调用的虚拟net_price函数是Quote::net_price。作为一个结果,没有任何折扣。结果是9090
本练习的对象是指向Quote对象的智能指针。在这个在这种情况下,多态性如期发生。被调用的实际虚函Bulk_quote::net_price确保折扣被应用。因此,结果是6363。可以发现,在价格的计算中采用了30%的折扣。如果没有矛盾,解释为什么没有矛盾。
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include "quote.h"
#include "bulk_quote.h"
#include "limit_quote.h"
#include "disc_quote.h"
int main()
{
/**
* @brief ex15.28 outcome == 9090
*/
std::vector<Quote> v;
for(unsigned i = 1; i != 10; ++i)
v.push_back(Bulk_quote("sss", i * 10.1, 10, 0.3));
double total = 0;
for (const auto& b : v)
{
total += b.net_price(20);
}
std::cout << total << std::endl;
std::cout << "======================\n\n";
/**
* @brief ex15.29 outccome == 6363
*/
std::vector<std::shared_ptr<Quote>> pv;
for(unsigned i =1; i != 10; ++i)
pv.push_back(std::make_shared<Bulk_quote>(Bulk_quote("sss", i * 10.1, 10, 0.3)));
double total_p = 0;
for (auto p : pv)
{
total_p += p->net_price(20);
}
std::cout << total_p << std::endl;
return 0;
}
basket类
Exercise 15.30: 编写自己的Basket类版本,并使用它计算在前面练习中使用的相同交易的价格。
#ifndef BASKET_H
#define BASKET_H
#include "quote.h"
#include <set>
#include <memory>
// a basket of objects from Quote hierachy, using smart pointers.
class Basket
{
public:
// copy verison
void add_item(const Quote& sale)
{ items.insert(std::shared_ptr<Quote>(sale.clone())); }
// move version
void add_item(Quote&& sale)
{ items.insert(std::shared_ptr<Quote>(std::move(sale).clone())); }
double total_receipt(std::ostream& os) const;
private:
// function to compare needed by the multiset member
static bool compare(const std::shared_ptr<Quote>& lhs,
const std::shared_ptr<Quote>& rhs)
{ return lhs->isbn() < rhs->isbn(); }
// hold multiple quotes, ordered by the compare member
std::multiset<std::shared_ptr<Quote>, decltype(compare)*>
items{ compare };
};
#endif // BASKET_H
#include "basket.h"
double Basket::total_receipt(std::ostream &os) const
{
double sum = 0.0;
for(auto iter = items.cbegin(); iter != items.cend();
iter = items.upper_bound(*iter))
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// @note this increment moves iter to the first element with key
// greater than *iter.
{
sum += print_total(os, **iter, items.count(*iter));
} // ^^^^^^^^^^^^^ using count to fetch
// the number of the same book.
os << "Total Sale: " << sum << std::endl;
return sum;
}
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <fstream>
#include "quote.h"
#include "bulk_quote.h"
#include "limit_quote.h"
#include "disc_quote.h"
#include "basket.h"
int main()
{
Basket basket;
for (unsigned i = 0; i != 10; ++i)
basket.add_item(Bulk_quote("Bible", 20.6, 20, 0.3));
for (unsigned i = 0; i != 10; ++i)
basket.add_item(Bulk_quote("C++Primer", 30.9, 5, 0.4));
for (unsigned i = 0; i != 10; ++i)
basket.add_item(Quote("CLRS", 40.1));
std::ofstream log("log.txt", std::ios_base::app|std::ios_base::out);
basket.total_receipt(log);
return 0;
}