博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c/c++ 继承与多态 容器与继承3
阅读量:4506 次
发布时间:2019-06-08

本文共 4213 字,大约阅读时间需要 14 分钟。

巩固了容器里放智能指针的用法,但是有个问题,对于使用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 
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 
#include
class Basket{ public: /* void add_item(const std::shared_ptr
& sale){ items.insert(sale); } */ void add_item(const Quote& sale){ items.insert(std::shared_ptr
(sale.clone())); } void add_item(Quote&& sale){ items.insert(std::shared_ptr
(std::move(sale).clone())); } double total_receipt(std::ostream&) const; private: static bool compare(const std::shared_ptr
& lhs, const std::shared_ptr
& rhs){ return lhs->isbn() < rhs->isbn(); } std::multiset
, 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 
#include
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

1414315-20181106214320230-961379709.jpg

本人微信:xiaoshitou5854

转载于:https://www.cnblogs.com/xiaoshiwang/p/10220481.html

你可能感兴趣的文章
学习的一点遭遇
查看>>
verilog中assign和always@(*)的区别和值得注意
查看>>
cache、session与cookie
查看>>
Ant 入门
查看>>
新东方6级听写考点笔记
查看>>
MySQL积累
查看>>
gulp详细入门教程
查看>>
学习中 C 相关一些试题和答案
查看>>
python中的可迭代对象与迭代器
查看>>
WebKit的已实施srcset图像响应属性
查看>>
suggestion开发小结以及 对键盘事件的总结(针对中文输入法状态)
查看>>
Nio Client
查看>>
数据库 chapter 16 XML数据库
查看>>
spring mvc jsp运行不起来的问题
查看>>
tkinter笔记005-输入框
查看>>
大数据概述
查看>>
SpringBoot 密码MD5加密
查看>>
Mac MySQL启动不了解决办法(MySQL卸载重新安装教程)
查看>>
连通块
查看>>
servlet.txt笔记
查看>>