c/c++语言开发共享c/c++ 继承与多态 容器与继承3

“c/c++ 继承与多态 容器与继承2” 巩固了容器里放智能指针的用法,但是有个问题,对于使用Basket类的用户来说,必须添加的是智能指针,如果能直接添加一个普通的类的对象的话,用起来就方便的多了,所以改进一下Basket类的add_item接口。 新的接口:一个是拷贝给定的对象,另一个是移动对象 …


巩固了容器里放智能指针的用法,但是有个问题,对于使用basket类的用户来说,必须添加的是智能指针,如果能直接添加一个普通的类的对象的话,用起来就方便的多了,所以改进一下basket类的add_item接口。

新的接口:一个是拷贝给定的对象,另一个是移动对象。

void add_item(const quote& sale);//左值拷贝 void add_item(quote&& sale);//右值移动

关键点:

1,由于类quote没有自定义的拷贝控制成员(拷贝构造函数,赋值语句等),所以,编译器才能自动生成移动构造函数,后面要用到编译器生成移动构造函数。

2,由于key是智能指针,所以在方法add_item里必须要有new,问题来了,new谁呢,只能new父类quote,但是new了quote后,子类部分就被切除掉了。

3,为了解决在2处的问题,在quote和它的子类里添加辅助的虚函数,来得到正确的指针。得到了正确的普通指针就可以用普通指针做出智能指针了。

quote4.h

#ifndef __quote4_h__ #define __quote4_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 quote* clone() const & {     //调用合成的拷贝构造函数     return new quote(*this);   }    ///调用此方法的对象是右值的时候   virtual quote* clone() && {     //调用合成的移动构造函数     return new quote(std::move(*this));   }      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){}     //调用此方法的对象是左值的时候   bulk_quote* clone() const & {     //调用合成的拷贝构造函数     return new bulk_quote(*this);   }    ///调用此方法的对象是右值的时候   bulk_quote* clone() && {     //调用合成的移动构造函数     return new bulk_quote(std::move(*this));   }       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 

quote4.cpp

#include "quote4.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;   } }  

basket2.h

#ifndef __basket2_h__ #define __basket2_h__ #include "quote4.h" #include <set> #include <memory>   class basket{  public:   /*   void add_item(const std::shared_ptr<quote>& sale){     items.insert(sale);   }   */    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}; };  #endif 

basket2.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 "quote4.h" #include "basket2.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;   quote q1("01", 100);   bulk_quote bq1("01", 100, 2, 0.1);   bsk.add_item(quote("01", 100));    bsk.add_item(bulk_quote("01", 100, 2, 0.1));    bsk.total_receipt(std::cout); } 

c/c++ 学习互助qq群:877684253

c/c++ 继承与多态 容器与继承3

本人微信:xiaoshitou5854

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/605638.html

(0)
上一篇 2021年5月13日
下一篇 2021年5月13日

精彩推荐