#include <iostream>
#include <string>
#include <memory>
#include <functional>
#include <map>
#include <vector>
#include <set> class Quote
{
friend double print_total(std::ostream &os, const Quote &item, std::size_t n);
private:
std::string Isbn;
protected:
double price;
public:
Quote() = default; Quote(const std::string &BookNm, double o_price)
: Isbn(BookNm),
price(o_price)
{
std::cout << "Quot constructor" << std::endl;
} Quote(const Quote &rhs)
: Isbn(rhs.Isbn),
price(rhs.price)
{
std::cout << "Quot copy constructor" << std::endl;
} //赋值运算符完成析构和拷贝工作
Quote &operator=(const Quote &rhs)
{
//考虑自赋值情况
if (this != &rhs)
{
Isbn = rhs.Isbn;
price = rhs.price; } return *this;
} //主要不是动态内存,不需要做窃取资源
Quote(Quote &&rhs)
: Isbn(std::move(rhs.Isbn)),
price(std::move(rhs.price))
{
std::cout << "Quote move copy constructor" << std::endl;
} ~Quote()
{
std::cout << "~Quote()" << std::endl;
} public:
std::string IsBn() const
{
return Isbn;
} //动态拷贝自己一份给智能指针
virtual Quote *clon() const &
{
return new Quote(*this);
} virtual Quote *clon() &&
{
return new Quote(std::move(*this));
} //虚函数定义给子类自己定义价格的方式
virtual double net_price(std::size_t n) const
{
return price * n;
} virtual void Debug() const
{
std::cout << "This is Quote Class" << std::endl;
std::cout << "ISBN: " << Isbn << std::endl;
std::cout << "Price: " << price << std::endl;
} }; double print_total(std::ostream &os, const Quote &item, std::size_t n)
{
auto price_total = item.net_price(n);
std::cout << "ISBN: " << item.IsBn() << std::endl;
std::cout << "Bugs: " << n << " Price: " << price_total << std::endl; return price_total;
} class bulk_quote : public Quote
{
private:
double discount;
std::size_t min_num; public:
//继承基类构造,初始化基类部分
// using Quote::Quote; bulk_quote() = delete; bulk_quote(const std::string &bookNm, double o_price, double discount_, std::size_t min_num_)
: Quote(bookNm, o_price),
discount(discount_),
min_num(min_num_)
{
std::cout << "bulk_quote constructor" << std::endl;
} bulk_quote(const bulk_quote &rhs)
: Quote(rhs) //调用基类构造,用rhs的基类部分初始化自己的基类
{
//如果派生类有自己的数据可以在这
discount = rhs.discount;
min_num = rhs.min_num;
} bulk_quote &operator=(const bulk_quote &rhs)
{
//基类赋值运算符使用rhs基类初始化
Quote::operator=(rhs);
discount = rhs.discount;
min_num = rhs.min_num;
return *this;
} bulk_quote(bulk_quote &&rhs)
: Quote(std::move(rhs)) //调用基类移动构造
{
discount = std::move(rhs.discount);
min_num = std::move(rhs.min_num);
} bulk_quote &operator=(bulk_quote &&rhs)
{
Quote::operator=(std::move(rhs)); //基类移动赋值运算符
discount = std::move(rhs.discount);
min_num = std::move(rhs.min_num);
return *this;
} public:
double net_price(std::size_t n) const override
{
if (n >= min_num)
{
return price * ( - discount) * n;
} else
{
return price * n;
}
} void Debug() const override
{
std::cout << "This is bulk_quote Class" << std::endl;
std::cout << "DISCOUNT: " << discount << std::endl;
std::cout << "Min_qty: " << min_num << std::endl;
std::cout << "Price: " << price << std::endl;
} bulk_quote *clon() const &override
{
return new bulk_quote(*this);
} bulk_quote *clon() &&override
{
return new bulk_quote(std::move(*this));
} }; class basket
{
public:
void add_item(const Quote &quote)
{
items.insert(std::shared_ptr<Quote>(quote.clon()));
} void add_item(Quote &&quote)
{
items.insert(std::shared_ptr<Quote>(std::move(quote).clon()));
} void print_recent(std::ostream &os) const
{
auto sum_price = ;
for (auto iter = items.cbegin();
iter != items.cend();
iter = items.upper_bound(*iter))
{
sum_price += print_total(os, **iter, items.count(*iter));
} std::cout << "\t\t\t total_price: " << sum_price << std::endl;
} private:
static bool compara(const std::shared_ptr<Quote> &c1, const std::shared_ptr<Quote> &c2)
{
return c1->IsBn() > c2->IsBn();
} std::multiset<std::shared_ptr<Quote>, decltype(compara) * > items{compara};
}; int main(int argc, char *argv[])
{ Quote A("烤香肠", ), B("炸面板", ), C("其他食品", );
bulk_quote D("面包", , 0.9, ), E("可乐", , 0.8, ); basket buy; buy.add_item(A);
buy.add_item(B);
buy.add_item(C); for (int i = ; i < ; i++)
{
buy.add_item(D);
buy.add_item(E);
} buy.print_recent(std::cout); return ;
}

C++:(拷贝,继承,智能指针)练习的更多相关文章

  1. c/c++ 继承与多态 文本查询的小例子(非智能指针版本)

    问题:在上一篇继承与多态 文本查询的小例子(智能指针版本)在Query类里使用的是智能指针,只把智能指针换成普通的指针,并不添加拷贝构造方法,会发生什么呢? 执行时,代码崩掉. 分析下面一行代码: Q ...

  2. c/c++ 继承与多态 文本查询的小例子(智能指针版本)

    为了更好的理解继承和多态,做一个文本查询的小例子. 接口类:Query有2个方法. eval:查询,返回查询结果类QueryResult rep:得到要查询的文本 客户端程序的使用方法: //查询包含 ...

  3. C++ 拷贝控制和资源管理,智能指针的简单实现

    C++ 关于拷贝控制和资源管理部分的笔记,并且介绍了部分C++ 智能指针的概念,然后实现了一个基于引用计数的智能指针.关于C++智能指针部分,后面会有专门的研究. 通常,管理类外资源的类必须定义拷贝控 ...

  4. C++智能指针详解

    本文出自http://mxdxm.iteye.com/ 一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete.程序员忘记 delete,流程太复杂,最 ...

  5. C++11智能指针

    今晚跟同学谈了一下智能指针,突然想要看一下C++11的智能指针的实现,因此下了这篇博文. 以下代码出自于VS2012 <memory> template<class _Ty> ...

  6. 【转】C++ 智能指针详解

    一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete.程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 ...

  7. c++ 中的8种智能指针[转]

    一.简介 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete.程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 ...

  8. Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6786239 Android 系统的运行时库层代 ...

  9. shared_ptr智能指针源码剖析

    (shared_ptr)的引用计数本身是安全且无锁的,但对象的读写则不是,因为 shared_ptr 有两个数据成员,读写操作不能原子化.根据文档 (http://www.boost.org/doc/ ...

随机推荐

  1. 为centos虚拟机配置固定ip

    在virtual上安装centos虚拟机以后,发现虚拟机没有ip,无法联网 将虚拟机的网络适配器改为桥接模式,桥接到物理机的无线网卡 为虚拟机配置固定IP(vi /etc/sysconfig/netw ...

  2. 第14讲:嵌入式SQL语言(基本技巧)

    一.交互式SQL的局限 & 嵌入式SQL的必要性 专业人员(如DBA)可以熟练地运用交互式SQL语言,但普通用户却不是那么容易上手,所以需要通过数据库应用程序来使用数据库.编写一个可以与数据库 ...

  3. Linux里的2>&1的理解

    转载自:https://blog.csdn.net/ggxiaobai/article/details/53507530 我们在Linux下经常会碰到nohup command>/dev/nul ...

  4. Leetcode题库——19.删除链表的倒数第 n 个节点【##】

    @author: ZZQ @software: PyCharm @file: removeNthFromEnd.py @time: 2018/9/26 21:56 说明:给定一个链表,删除链表的倒数第 ...

  5. HTML和CSS <h1> --3-- <h1>

    标签语义化,让网页更好的被搜索引擎理解 标签的用途:我们学习网页制作时,常常会听到一个词,语义化.那么什么叫做语义化呢,说的通俗点就是:明白每个标签的用途(在什么情况下使用此标签合理)比如,网页上的文 ...

  6. 使用testng多线程来测试成交编号重复的问题

    1.首先编写一个测试用的 function CREATE OR REPLACE FUNCTION getDealmainNo_test(dealdate IN varchar2, productcod ...

  7. ES6 常用1

    ( (1)交换变量的值 ) [x, y] = [y, x]; ( (2)从函数返回多个值 // 返回一个数组function example() { return [1, 2, 3]; } var [ ...

  8. 深入理解JAVA虚拟机阅读笔记6——线程安全与锁优化

    线程安全:如果一个对象可以安全的被多个线程同时使用,那它就是线程安全的. 一.Java中的线程安全 1.不可变 不可变的对象一定是线程安全的.String.枚举类型.java.lang.Number的 ...

  9. 第219天:Angular---过滤器

    在Angular中,过滤器的功能主要是格式化数据表达式,且可以自定义过滤器.作用域(scope)主要服务于页面模板,在控制器和页面中起桥梁作用,保存模板中的数据对象,为模板中的元素提供方法和属性. 一 ...

  10. static关键字的总结

    C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用. 1.面向过程设计中的st ...