C++primer练习15.15-33
练习15.15
重新定义Bulk_quote
class Disc_quote:public Quote{ public: Disc_quote()=default; Disc_quote(const std::string& book,double p,std::size_t qty,double disc): Quote(book,p),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 p,std::size_t qty,double disc) :Disc_quote(book,p,qty,disc){ } double net_price (std::size_t cnt)const override{ if((cnt-min_qty)>0) return cnt * (1-discount) * price+(cnt-min_qty)*price; else return cnt * (1-discount) * price; } void debug()override { std::cout<<" min_qty: "<<min_qty<<" discount: "<<discount<<std::endl; } private: std::size_t min_qty=0; double discount=0.0; };
练习15.17
尝试定义一个Disc_quote,看看编译器错误提示
[Error] use of deleted function 'Disc_quote::Disc_quote()'
练习15.18
假设给定类,同时已知每个对象的类型如注释所示,判断哪些语句合法
(1)合法
(2)不合法,派生访问说明符是private,不能访问public
(3)不合法,派生访问说明符是protected
(4)合法
(5)不合法,继承类都不合法
(6)不合法,继承类都不合法
练习15.19
::如果派生类继承基类的方式是公有的或者受保护的,则派生类的成员和友元可以使用派生类向基类的类型转换;反之,如果派生类继承基类的方式是私有的,则不能使用;派生类向其直接基类的类型转换对于派生类的成员和函数来说永远是可访问的。
只有Derived_from_private不合法
练习15.21
(b)将geometry定义为几何类,在其下定义方格圆等派生类
练习15.22
虚函数,求周长面积,保护成员有长宽(向量图)
练习15.23
::将fcn函数设计成int fcn(),p2->fcn(42)的调用会出错
练习15.24
那种类需要虚析构函数?虚析构函数必须执行什么样的操作
::作为基类通常都要虚析构函数,虚析构函数在数据成员为指针类的情况需要自定义析构函数,其它则合成即可
练习15.25
::如若去掉Bulk_price将无法默认初始化
练习15.26
class Quote{ public: 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 price*n; } Quote()=default; Quote(const Quote& a):bookNo(a.bookNo),price(a.price){std::cout<<"基类拷贝构造"<<std::endl; } Quote& operator=(const Quote& a){ bookNo=a.bookNo; price=a.price; std::cout<<"基类赋值"<<std::endl; return *this; } Quote(Quote&& a):bookNo(std::move(a.bookNo)),price(std::move(a.price)) {std::cout<<"基类移动构造"<<std::endl;} virtual ~Quote(){std::cout<<"基类析构"<<std::endl;} virtual void debug(){ std::cout<<"bookNo: "<<bookNo<<" price: "<<price<<std::endl; } private: std::string bookNo; protected: double price =0.0; }; double print_total(std::ostream &os,const Quote& item,std::size_t n) { double ret=item.net_price(n); os<<" ISBN: "<<item.isbn() <<" # sold: "<<n<<" total due: "<<ret<<std::endl; } class Disc_quote:public Quote{ public: Disc_quote()=default; Disc_quote(const std::string& book,double p,std::size_t qty,double disc): Quote(book,p),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 p,std::size_t qty,double disc) :Disc_quote(book,p,qty,disc){ } Bulk_quote(const Bulk_quote&a):Disc_quote(a),min_qty(a.min_qty),discount(a.discount) {std::cout<<"Bulk_quote拷贝构造"<<std::endl;} Bulk_quote(Bulk_quote&& a):Disc_quote(std::move(a)), min_qty(std::move(a.min_qty)),discount(std::move(a.discount)) {std::cout<<"Bulk_quote移动构造"<<std::endl;} Bulk_quote& operator=(const Bulk_quote&a) { Quote:operator=(a); min_qty=a.min_qty; discount=a.discount; std::cout<<"Bulk_quote赋值运算"<<std::endl; } ~Bulk_quote(){ std::cout<<"Bulk_quote析构函数"<<std::endl; } double net_price (std::size_t cnt)const override{ if((cnt-min_qty)>0) return cnt * (1-discount) * price+(cnt-min_qty)*price; else return cnt * (1-discount) * price; } void debug()override { std::cout<<" min_qty: "<<min_qty<<" discount: "<<discount<<std::endl; } private: std::size_t min_qty=0; double discount=0.0; };
::构造先从基类部分开始,析构基类部分结束,顺序都是逐层进行,虚析构函数不用显示调用
练习15.27
class Bulk_quote:public Disc_quote{ public: Bulk_quote()=default; /*Bulk_quote(const std::string& book,double p,std::size_t qty,double disc) :Disc_quote(book,p,qty,disc){ } */ Bulk_quote(const Bulk_quote&a):Disc_quote(a),min_qty(a.min_qty),discount(a.discount) {std::cout<<"Bulk_quote拷贝构造"<<std::endl;} Bulk_quote(Bulk_quote&& a):Disc_quote(std::move(a)), min_qty(std::move(a.min_qty)),discount(std::move(a.discount)) {std::cout<<"Bulk_quote移动构造"<<std::endl;} Bulk_quote& operator=(const Bulk_quote&a) { Quote:operator=(a); min_qty=a.min_qty; discount=a.discount; std::cout<<"Bulk_quote赋值运算"<<std::endl; } using Disc_quote::Disc_quote; ~Bulk_quote(){ std::cout<<"Bulk_quote析构函数"<<std::endl; } double net_price (std::size_t cnt)const override{ if((cnt-min_qty)>0) return cnt * (1-discount) * price+(cnt-min_qty)*price; else return cnt * (1-discount) * price; } void debug()override { std::cout<<" min_qty: "<<min_qty<<" discount: "<<discount<<std::endl; } private: std::size_t min_qty=0; double discount=0.0; };
练习15.28
std::vector<Quote> a; a.push_back(Bulk_quote("1234",50,1,1)); for(auto d:a) std::cout<<d.net_price(1)<<std::endl;
练习15.29
std::vector<std::shared_ptr<Quote>> a; a.push_back(std::make_shared<Bulk_quote>("1234",50,1,1)); for(auto d:a) std::cout<<d->net_price(1)<<std::endl;
练习15.31
(a)3个WordQuery对象,1个NotQuery对象,1个AndQuery对象,1个OrQuery对象
(b)同a
(c)4个WordQuery对象,2个AndQuery对象,1个OrQuery对象
练习15.32
当一个Query类型的对象被拷贝移动赋值销毁,将分别发生什么?
:: 共享shared_ptr指针,销毁时判断计数
练习15.33
当一个Query_base 被拷贝移动赋值销毁时 ,将分别发生什么?
::实际上没有数据成员,啥也不会发生