c/c++ 继承与多态 容器与继承2
程序员文章站
2022-07-02 18:00:49
"c/c++ 继承与多态 容器与继承1" 说明了容器里使用继承关系的方法,这里再弄一个练习,巩固一下。 做一个类Basket,它有个multiset成员,key是智能指针std::shared_ptr\,由于key是自定义对象,所有必须给一个比较key的函数decltype(compare) ,关于 ......
说明了容器里使用继承关系的方法,这里再弄一个练习,巩固一下。
做一个类basket,它有个multiset成员,key是智能指针std::shared_ptr<quote>,由于key是自定义对象,所有必须给一个比较key的函数decltype(compare)*,关于自定义key的set,参考 。有个公有的additem成员方法,
quote3.h
#ifndef __quote3_h__ #define __quote3_h__ #include <iostream> class quote{ public: quote() = default; quote(const std::string& book, double pri) :bookno(book), price(pri){} std::string isbn() const{return bookno;} virtual double net_price(std::size_t n)const{ return n * price; } virtual void debug()const{ std::cout << bookno << " " << price << std::endl; } virtual ~quote() = default; 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 qyn, double disc):quote(book, price), quantity(qyn), discount(disc){} double net_price(std::size_t) const override = 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 qyn, double disc) :disc_quote(book, price, qyn, disc){} double net_price(std::size_t) const override; }; class min_quote : public disc_quote{ public: min_quote() = default; min_quote(const std::string& book, double price, std::size_t qyn, double disc) :disc_quote(book, price, qyn, disc){} double net_price(std::size_t) const override; }; #endif
quote3.cpp
#include "quote3.h" double bulk_quote::net_price(std::size_t cnt) const{ if(cnt >= quantity){ return cnt * (1 - discount) * price; } else{ return cnt * price; } } double min_quote::net_price(std::size_t cnt) const{ if(cnt < quantity){ return cnt * (1 - discount) * price; } else{ return cnt * price; } }
basket.h
#ifndef __basket_h__ #define __basket_h__ #include "quote3.h" #include <set> #include <memory> class basket{ public: void add_item(const std::shared_ptr<quote>& sale){ items.insert(sale); } 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}; }; #endif
basket.cpp
#include "basket.h" double print_total(std::ostream& os, const quote& item, size_t n); 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)){ sum += print_total(os, **iter, items.count(*iter)); } os << "total sale: " << sum << std::endl; return sum; }
main.cpp
#include "quote3.h" #include "basket.h" #include <vector> #include <iostream> double print_total(std::ostream& os, const quote& item, size_t n){ double ret = item.net_price(n); os << "isbn: " << item.isbn() << " # sold: " << n << " total due: " << ret << std::endl; return ret; } int main(){ basket bsk; //bsk.add_item(std::make_shared<quote>("01", 100)); bsk.add_item(std::make_shared<bulk_quote>("01", 100, 2, 0.1)); bsk.add_item(std::make_shared<bulk_quote>("01", 100, 2, 0.1)); bsk.add_item(std::make_shared<bulk_quote>("01", 100, 2, 0.1)); bsk.total_receipt(std::cout); }
执行结果1:
isbn: 01 # sold: 3 total due: 270 total sale: 270
把main函数改成下面:
int main(){ basket bsk; bsk.add_item(std::make_shared<quote>("01", 100)); //bsk.add_item(std::make_shared<bulk_quote>("01", 100, 2, 0.1)); bsk.add_item(std::make_shared<bulk_quote>("01", 100, 2, 0.1)); bsk.add_item(std::make_shared<bulk_quote>("01", 100, 2, 0.1)); bsk.total_receipt(std::cout); }
执行结果2:
isbn: 01 # sold: 3 total due: 300 total sale: 300
代码有点长,主要的关注点:
- 容器里放的是智能指针
- 第一次添加的智能指针,如果是quote类型,执行结果就是执行结果2;如果是bulk_quote类型,执行结果就是执行结果1;