习题15.3:
#ifndef QUOTE_H
#define QUOTE_H
#include <iostream>
#include <string>
class Quote
{
public:
//构造函数
Quote() = default;
Quote(const std::string &book, const double &p) :bookNo(book), price(p){ }
//返回ISBN编号
std::string isbn()const{ return bookNo; }
//虚函数 返回当前计算方法的总价格
virtual double net_price(std::size_t n)const{ return n*price; }
//虚析构函数 动态绑定
virtual ~Quote() = default;
private:
std::string bookNo;//书籍的ISBN编号
protected:
double price;//未打折价格
};
double print_total(std::ostream &os, const Quote &item, std::size_t n)
{
double ret = item.net_price(n);
os << "ISBN: " << item.isbn() << " total due: " << ret << std::endl;
return ret;
}
#endif
习题15.5_6_7:
#ifndef QUOTE_H
#define QUOTE_H
#include <iostream>
#include <string>
class Quote
{
public:
//构造函数
Quote() = default;
Quote(const std::string &book, const double &p) :bookNo(book), price(p){ }
//返回ISBN编号
std::string isbn()const{ return bookNo; }
//虚函数 返回当前计算方法的总价格
virtual double net_price(std::size_t cnt)const{ return cnt*price; }
//虚析构函数 动态绑定
virtual ~Quote() = default;
private:
std::string bookNo;//书籍的ISBN编号
protected:
double price;//未打折价格
};
#endif
#ifndef BULK_QUOTE_H
#define BULK_QUOTE_H
#include "Quote.h"
class Bulk_quote :public Quote
{
public:
Bulk_quote() = default;
Bulk_quote(const std::string &book, const double &p, std::size_t least, double d)
:Quote(book, p), min_qty(least), discount(d){ }
double net_price(std::size_t cnt)const override{
if (cnt >= min_qty)
return cnt*price*(1 - discount);
else
return cnt*price;
};
private:
std::size_t min_qty = 0;
double discount = 0.0;
};
#endif
#ifndef BOUND_QUOTE_H
#define BOUND_QUOTE_H
#include "Quote.h"
class Bound_quote:public Quote
{
public:
Bound_quote() = default;
Bound_quote(const std::string &book,const double &p,std::size_t most,double d)
:Quote(book, p), max_qty(most), discount(d){ }
double net_price(std::size_t cnt)
{
if (cnt <= max_qty)
return cnt*price*(1 - discount);
else
return max_qty*price*(1 - discount) + (cnt - max_qty)*price;
}
private:
std::size_t max_qty = 0;
double discount = 0.0;
};
#endif
习题15.15_16:
#ifndef DISC_QUOTE_H
#define DISC_QUOTE_H
#include "Quote.h"
class Disc_quote:public Quote
{
public:
Disc_quote() = default;
Disc_quote(const std::string &book, const double &p, std::size_t qty, double d)
:Quote(book, p), quantity(qty), discount(d){ }
double net_price(std::size_t cnt)const = 0;
private:
std::size_t quantity = 0;
double discount = 0.0;
};
#endif
#ifndef BULK_QUOTE_H
#define BULK_QUOTE_H
#include "Disc_quote.h"
class Bulk_quote :public Disc_quote
{
public:
Bulk_quote() = default;
Bulk_quote(const std::string &book, const double &p, std::size_t least, double d)
:Disc_quote(book, p, least, d){ }
double net_price(std::size_t cnt)const override
{
return (cnt >= min_qty) ? cnt*price*(1 - discount) : cnt*price;
};
std::ostream &debug(std::ostream &os)const override
{
Quote::debug(os);
os << "最小购买量:min_qty 折扣:discount ";
return os;
}
private:
std::size_t min_qty = 0;
double discount = 0.0;
};
#endif
#ifndef BOUND_QUOTE_H
#define BOUND_QUOTE_H
#include "Disc_quote.h"
class Bound_quote :public Disc_quote
{
public:
Bound_quote() = default;
Bound_quote(const std::string &book,const double &p,std::size_t most,double d)
:Disc_quote(book, p, most, d){ }
double net_price(std::size_t cnt)const
{
return (cnt <= max_qty) ? cnt*price*(1 - discount)
: max_qty*price*(1 - discount) + (cnt - max_qty)*price;
}
std::ostream &debug(std::ostream &os)const override
{
Quote::debug(os);
os << "最大购买量:max_qty 折扣:discount ";
return os;
}
private:
std::size_t max_qty = 0;
double discount = 0.0;
};
#endif
#ifndef QUOTE_H
#define QUOTE_H
#include <iostream>
#include <string>
class Quote
{
public:
//构造函数
Quote() = default;
Quote(const std::string &book, const double &p) :bookNo(book), price(p){ }
//返回ISBN编号
std::string isbn()const{ return bookNo; }
//虚函数 返回当前计算方法的总价格
virtual double net_price(std::size_t cnt)const{ return cnt*price; }
//虚函数 显示类的数据成员
virtual std::ostream &debug(std::ostream &os)const
{
os << "ISBN编号:bookNo 原价格:price ";
return os;
}
//虚析构函数 动态绑定
virtual ~Quote() = default;
private:
std::string bookNo;//书籍的ISBN编号
protected:
double price;//未打折价格
};
#endif
习题15.21:
#ifndef SHAPE_H
#define SHAPE_H
#include <string>
#include <utility>
class Shape
{
public:
using Coordinate = std::pair<double, double>;
Shape() = default;
Shape(const std::string &n) :name(n){ }
virtual const double area()const = 0;
virtual const double perimeter()const = 0;
virtual ~Shape() = default;
private:
std::string name;
};
class Rectangle:public Shape
{
public:
Rectangle() = default;
Rectangle(const std::string &s,
const Coordinate &p1, const Coordinate &p2,
const Coordinate &p3, const Coordinate &p4)//注意const
:Shape(s), a(p1), b(p2),c(p3), d(p4){ }
const double area()const;
const double perimeter()const;
~Rectangle() = default;
protected://为了让Rectangle的派生类可以访问
Coordinate a;
Coordinate b;
Coordinate c;
Coordinate d;
private:
std::pair<Coordinate, Coordinate> corner()const;//工具函数 找出对定的两点
};
class Square :public Rectangle
{
public:
Square() = default;
Square(const std::string &s,
const Coordinate &p1, const Coordinate &p2,
const Coordinate &p3, const Coordinate &p4)
:Rectangle(s, p1, p2, p3, p4){ }
~Square() = default;
//const double area()const;//完全可以使用Rect版本而不需要自己定义
//const double perimeter()const;//可以给出新定义just for efficiency.
};
std::pair<Shape::Coordinate, Shape::Coordinate> Rectangle::corner()const
{
if (a.first != b.first && a.second != b.second)
return std::make_pair(a, b);
else if (a.first != c.first && a.second != c.second)
return std::make_pair(a, c);
else
return std::make_pair(a, d);
}
const double Rectangle::area()const
{
auto p = corner();
Coordinate c1 = p.first, c2 = p.second;
return abs((c1.first - c2.first)*(c1.second - c2.second));
}
const double Rectangle::perimeter()const
{
auto p = corner();
Coordinate c1 = p.first, c2 = p.second;
return 2 * abs((c1.first - c2.first) + (c1.second - c2.second));
}
#endif
#include "Shape.h"
#include <iostream>
int main()
{
//const std::string s("rect1");
//Rectangle r1(s, { 1, 1 }, { 1, 5 }, { 4, 1 }, { 4, 5 });
//std::cout << r1.area() << " " << r1.perimeter() << std::endl;
Square s1("square1", { 0, 0 }, { 1, 1 }, { 0, 1 }, { 1, 0 });
std::cout << s1.area() << " " << s1.perimeter() << std::endl;
getchar();
return 0;
}
习题15.26:
Quote.h:
#ifndef QUOTE_H
#define QUOTE_H
#include <iostream>
#include <string>
#include <stdexcept>
#ifndef _MSC_VER
#define NOEXCEPT noexcept
#else
#define NOEXCEPT
#endif
class Quote
{
public:
//构造函数
Quote(){ std::cout << "Quote: default constructor" << std::endl; }
Quote(const std::string &book, const double &p) :bookNo(book), price(p)
{
std::cout << "Quote: constuctor func" << std::endl;
}
//拷贝构造函数
Quote(const Quote &q) :bookNo(q.bookNo), price(q.price)
{
std::cout << "Quote: copy constuctor func" << std::endl;
}
//拷贝赋值运算符
Quote &operator=(const Quote &rhs)
{
if (this != &rhs)
{
bookNo = rhs.bookNo;
price = rhs.price;
}
std::cout << "Quote: copy operator= func" << std::endl;
return *this;
}
//移动构造函数
Quote(const Quote &&rhs)NOEXCEPT:bookNo(std::move(rhs.bookNo)), price(std::move(rhs.price))
{
std::cout << "Quote: move constructor func" << std::endl;
}
//移动赋值运算符
Quote &operator=(const Quote &&rhs)NOEXCEPT
{
if (this != &rhs)
{
bookNo = std::move(rhs.bookNo);
price = std::move(rhs.price);
}
std::cout << "Quote: move operator= func" << std::endl;
return *this;
}
//返回ISBN编号
std::string isbn()const{ return bookNo; }
//虚函数 返回当前计算方法的总价格
virtual double net_price(std::size_t cnt)const{ return cnt*price; }
//虚函数 显示类的数据成员
virtual std::ostream &debug(std::ostream &os)const
{
os << "ISBN编号:bookNo 原价格:price ";
return os;
}
//虚析构函数 动态绑定
virtual ~Quote()
{
std::cout << "~Quote deconstructor func" << std::endl;
}
private:
std::string bookNo;//书籍的ISBN编号
protected:
double price;//未打折价格
};
#endif
Disc_quote:
#ifndef DISC_QUOTE_H
#define DISC_QUOTE_H
#include "Quote.h"
class Disc_quote:public Quote
{
public:
Disc_quote(){ std::cout << "Disc_quote: default constructor func" << std::endl; }
Disc_quote(const std::string &book, const double &p, std::size_t qty, double d)
:Quote(book, p), quantity(qty), discount(d)
{
std::cout << "Disc_quote: constructor func" << std::endl;
}
Disc_quote(const Disc_quote &d) :Quote(d), quantity(d.quantity), discount(d.discount)
{
std::cout << "Disc_quote: copy constructor func" << std::endl;
}
Disc_quote &operator=(const Disc_quote &rhs)
{
if (this != &rhs)
{
Quote::operator=(rhs);
quantity = rhs.quantity;
discount = rhs.discount;
}
std::cout << "Disc_quote: copy operator= func" << std::endl;
return *this;
}
//正好此处没用std::move看看是否影响
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//经检验,确实有影响。如果某一代没有用std::move显示调用移动构造或移动赋值
//例如,Disc_quote没move,则对Bulk_quote类对象进行显示移动构造或赋值时
//只有Bulk_quote的移动构造或赋值被调用,接下来只会回溯调用Disc_quote的拷贝
//赋值或构造函数,然后回溯调用Quote基类的拷贝,最终顺序是自基类向派生类显示
//所以一定不要在移动构造和赋值中忽视std::move的作用。
Disc_quote(const Disc_quote &&d)NOEXCEPT
:Quote(std::move(d)), quantity(std::move(d.quantity)), discount(std::move(d.discount))
{
std::cout << "Disc_quote: move constructor func" << std::endl;
}
Disc_quote &operator=(const Disc_quote &&rhs)NOEXCEPT
{
if (this != &rhs)
{
Quote::operator=(std::move(rhs));
quantity = std::move(rhs.quantity);
discount = std::move(rhs.discount);
}
std::cout << "Disc_quote: move operator= func" << std::endl;
return *this;
}
~Disc_quote(){ std::cout << "~Disc_quote deconstructor func" << std::endl; }
double net_price(std::size_t cnt)const = 0;
private:
std::size_t quantity = 0;
double discount = 0.0;
};
#endif
Bulk_quote:
#ifndef BULK_QUOTE_H
#define BULK_QUOTE_H
#include "Disc_quote.h"
class Bulk_quote :public Disc_quote
{
public:
Bulk_quote(){ std::cout << "Bulk_quote: default constructor" << std::endl; }
Bulk_quote(const std::string &book, const double &p, std::size_t least, double d)
:Disc_quote(book, p, least, d)
{
std::cout << "Bulk_quote: construtor func" << std::endl;
}
Bulk_quote(const Bulk_quote &b) :Disc_quote(b), min_qty(b.min_qty), discount(b.discount)
{
std::cout << "Bulk_quote: copy construcot func" << std::endl;
}
Bulk_quote &operator=(const Bulk_quote &rhs)
{
if (this != &rhs)
{
Disc_quote::operator=(rhs);
min_qty = rhs.min_qty;
discount = rhs.discount;
}
std::cout << "Bulk_quote: copy operator= func" << std::endl;
return *this;
}
Bulk_quote(const Bulk_quote &&b) NOEXCEPT
:Disc_quote(std::move(b)), min_qty(std::move(b.min_qty)), discount(std::move(b.discount))
{
std::cout << "Bulk_quote: move constructor func" << std::endl;
}
Bulk_quote &operator=(const Bulk_quote &&rhs)NOEXCEPT
{
if (this != &rhs)
{
Disc_quote::operator=(std::move(rhs));
min_qty = std::move(rhs.min_qty);
discount = std::move(rhs.discount);
}
std::cout << "Bulk_quote: move operator= func" << std::endl;
return *this;
}
double net_price(std::size_t cnt)const override
{
return (cnt >= min_qty) ? cnt*price*(1 - discount) : cnt*price;
};
std::ostream &debug(std::ostream &os)const override
{
Quote::debug(os);
os << "最小购买量:min_qty 折扣:discount ";
return os;
}
~Bulk_quote(){ std::cout << "~Bulk_quote: deconstructor func" << std::endl; }
private:
std::size_t min_qty = 0;
double discount = 0.0;
};
#endif
习题15.28_29:
#include "Quote.h"
#include "Disc_quote.h"
#include "Bulk_quote.h"
#include "Bound_quote.h"
#include <vector>
#include <memory>
using std::shared_ptr;
using std::make_shared;
double print_total(std::ostream &os, const Quote &item, std::size_t n);
int main()
{
std::vector<Quote> basket_q;
basket_q.push_back(Bulk_quote("1", 1, 5, 0.1));
basket_q.push_back(Bulk_quote("1", 2, 10, 0.1));
basket_q.push_back(Bulk_quote("1", 3, 10, 0.2));
basket_q.push_back(Bulk_quote("1", 4, 5, 0.3));
std::vector<shared_ptr<Quote>> basket;
basket.push_back(make_shared<Bulk_quote>("2", 1, 5, 0.1));
basket.push_back(make_shared<Bulk_quote>("2", 2, 10, 0.1));
basket.push_back(make_shared<Bulk_quote>("2", 3, 10, 0.2));
basket.push_back(make_shared<Bulk_quote>("2", 4, 5, 0.3));
double sum1 = 0, sum2 = 0;
for (auto q : basket_q)
{
sum1 += q.net_price(7);
}
for (auto pq : basket)
{
sum2 += pq->net_price(7);
}
std::cout << sum1 << " " << sum2 << std::endl;
getchar();
return 0;
}
double print_total(std::ostream &os, const Quote &item, std::size_t cnt)
{
double ret = item.net_price(cnt);
os << "ISBN: " << item.isbn() << " total due: " << ret << std::endl;
return ret;
}