前言
考虑到时间的紧迫性,不可能在像之前那样又是抄题并且全部完成了,这次我只写到30题,剩下的是一个综合练习,就不搞了-.-
15.2.1节练习
15.1
在类中被声明为virtual的成员,基类希望这种成员在派生类中重定义,除了构造函数外,任意非
static成员都可以为虚成员
15.2
protected可以被该类的成员,友元和派生类成员访问,而不可以被该类型的普通成员访问,而private
成员只能被基类和友元访问,派生类不可访问
15.3
#include<bits/stdc++.h>
using namespace std;
class Quote
{
public:
Quote()=default;
Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){};
double net_price(std::size_t n)const
{
return n*price;
}
double print_total(ostream&os,const Quote&item,size_t n)
{
double ret=item.net_price(n);
os<<"ISBN:"<<item.price<<"#sold:"<<n<<endl;
return ret;
}
virtual~Quote()=default;
private:
std::string bookNo;
protected:
double price=0.0;
};
int main()
{
Quote a("1001",10);
auto ret=a.print_total(cout,a,4);
cout<<ret<<endl;
return 0;
}
15.2.2节练习
15.4
class base{...}
(a)class Derived :public Derived{...}//错误,不能自己作为基类,又是派生类
(b)class Derived:private Base{...}//正确
(c)class Derived:public Base;//正确
15.5
class Bulk_quote:public Quote
{
public:
Bulk_quote()=default;
Bulk_quote(const std::string&,double,std::size_t ,double);
double net_price(std::size_t n)const;
private:
std::size_t min_qty=0;
double discount=0.0;
};
Bulk_quote::Bulk_quote(const std::string &s,double n,std::size_t min,double dis):Quote(s,n),min_qty(min),discount(dis){};
double Bulk_quote::net_price(std::size_t n)const
{
return n*price*discount;
}
15.6
#include<bits/stdc++.h>
using namespace std;
class Quote
{
public:
Quote()=default;
Quote(const std::string &book,double sales_price):bookNo(book),price(sales_price){};
virtual double net_price(std::size_t n)const
{
return n*price;
}
virtual~Quote()=default;
private:
std::string bookNo;
protected:
double price=0.0;
};
double print_total(ostream&os,const Quote&item,size_t n)
{
double ret=item.net_price(n);
os<<ret<<endl;
return ret;
}
class Bulk_quote:public Quote
{
public:
Bulk_quote()=default;
Bulk_quote(const std::string&,double,std::size_t ,double);
double net_price(std::size_t n)const override;
private:
std::size_t min_qty=0;
double discount=0.0;
};
Bulk_quote::Bulk_quote(const std::string &s,double n,std::size_t min,double dis):Quote(s,n),min_qty(min),discount(dis){};
double Bulk_quote::net_price(std::size_t n)const
{
return n*price*discount;
}
int main()
{
Quote a("1001",10);
auto ret=print_total(cout,a,4);
cout<<ret<<endl;
Bulk_quote b("werqw",11,1,0.3);
auto ans=print_total(cout,b,4);
cout<<ans<<endl;
return 0;
}
15.7
#include<bits/stdc++.h>
using namespace std;
class text
{
public:
text(int a,int b,double c):max_num(a),price(b),discount(c){};
void print_total(ostream&os,size_t num)
{
if(num<=max_num)
{
os<<num*price*discount<<endl;
}else
{
os<<max_num*price*discount+(num-max_num)*price<<endl;
}
return;
}
private:
int max_num;
int price;
double discount;
};
int main()
{
text a(100,3,0.3);
a.print_total(cout,12);
return 0;
}
15.2.3节练习
15.8
静态类型在编译时就确定好了,它是变量声明时的类型表达式生成的类型,而动态类型则是变量或者表达式表示内存中的对象的类型,其知道运行才会知道
15.9
传递给的是派生类对象则是其不同的情况
15.10
在要求使用基类对象的地方,允许使用派生类型对象来代替
15.3节练习
15.11
virtual void debug() {
cout << "bookNo:" << bookNo << " price:" << price << endl;
}
15.12
有必要,这就表示这个函数覆盖其基类的函数,有不能由其子类覆盖
15.13
class base{
public:
string name(){return basename;}
virtual void print(ostream&os){os<<basename;}
private:
string basename;
}
class derived:public base{
public:
void print(ostream&os){print(os);os<<" "<<i;};//加上override关键字修饰
private:
int i;
}
15.14
不想写,只要记住指针和引用类型可以实现运行时绑定即可。
15.4节练习
#include<iostream>
using namespace std;
class Quote
{
public:
virtual void debug() {
cout << "bookNo:" << bookNo << " price:" << price << endl;
}
Quote() = default;
Quote(const std::string& book, double sales_price) :bookNo(book), price(sales_price) {};
virtual double net_price(std::size_t n)const
{
return n * price;
}
virtual~Quote() = default;
private:
std::string bookNo;
protected:
double price = 0.0;
};
double print_total(ostream& os, const Quote& item, size_t n)
{
double ret = item.net_price(n);
os << ret << endl;
return ret;
}
//Disc_quote
class Disc_quote :public Quote{
public:
Disc_quote() = default;
Disc_quote(const std::string& book, double price, std::size_t qty, double disc) :
Quote(book, price), quantity(qty), discount(disc) {};
double net_price(std::size_t n)const = 0;
protected:
std::size_t quantity = 0;
double discount = 0;
};
class Bulk_quote :public Disc_quote{
public:
Bulk_quote() = default;
Bulk_quote(const std::string& book, double price, std::size_t qty, double disc) :Disc_quote(book, price, qty, disc) {};
double net_price(std::size_t)const override;
};
double Bulk_quote::net_price(std::size_t n)const {
if (n > quantity) {
return price * quantity * discount + (n - quantity) * price;
}
else {
return n * price * discount;
}
}
int main() {
Bulk_quote a("hello", 2, 3, 0.1);
cout << a.net_price(10) << endl;
return 0;
}
15.16
同上
15.17
不允许使用抽象类型的对象
15.5节练习
15.18
Base*p=&d1;//d1的类型是Pub_Derv
p=&d2;//d2的类型是Priv_Derv
p=&d3;//d3的类型是Prot_Derv
p=&dd1;//dd1的类型是Derived_from_Public
p=&dd2;//dd2的类型是Derived_from_Private
p=&dd3;//dd3的类型是Derived_from_Protected
只有当公有的继承时,才能进行派生类到基类的转换
15.19
void memfun(Base&b){b=*this};
同上,只有当时公有的继承时,才能进行派生类到基类的转化
15.20
不想作答-.-
15.21
记住普通用户实现代码,需要对象的接口,所以设为公有的,而实现者则是负责编写类的成员和友元,成员和友元可以访问对象所有
如果进一步考虑继承,就会出现第三种用户,即派生类,基类把它希望派生类能够使用的部分设置为保护的,不同用户不能访问保护区,而派生类及其友元
仍然不能访问私有成员
15.22
根据上题思想来设计
15.6节练习
15.23
参数类型相同来进行覆盖
15.7.1节练习
15.24
基类需要虚析构函数,啥操作都不需要执行
15.7.2节练习
15.25
对象的实例化时,没有参数也能实例化
15.26
#include<iostream>
using namespace std;
class Quote
{
public:
virtual void debug() {
cout << "bookNo:" << bookNo << " price:" << price << endl;
}
Quote(const Quote&);
Quote() = default;
Quote(const std::string& book, double sales_price) :bookNo(book), price(sales_price) {
cout << "Quote contructor is running" << endl;
}
virtual double net_price(std::size_t n)const
{
return n * price;
}
virtual~Quote() {
cout << "Quote destructor is running" << endl;
}
private:
std::string bookNo;
protected:
double price = 0.0;
};
Quote::Quote(const Quote& rhs) {
cout << "Quote" << endl;
bookNo = rhs.bookNo;
price = rhs.price;
}
double print_total(ostream& os, const Quote& item, size_t n)
{
double ret = item.net_price(n);
os << ret << endl;
return ret;
}
//Disc_quote
class Disc_quote :public Quote{
public:
Disc_quote() = default;
Disc_quote(const std::string& book, double price, std::size_t qty, double disc) :
Quote(book, price), quantity(qty), discount(disc) {
cout << "Disc_quote constructor is running" << endl;
}
~Disc_quote() {
cout << "Dis_quote destructor is running" << endl;
}
double net_price(std::size_t n)const = 0;
protected:
std::size_t quantity = 0;
double discount = 0;
};
class Bulk_quote :public Disc_quote{
public:
Bulk_quote(const Bulk_quote&);
Bulk_quote() = default;
Bulk_quote(const std::string& book, double price, std::size_t qty, double disc) :Disc_quote(book, price, qty, disc) {
cout << "Bulk_qutoe constructor is running" << endl;
}
double net_price(std::size_t)const override;
~Bulk_quote() {
cout << "Bulk_quote destructor is running" << endl;
}
};
double Bulk_quote::net_price(std::size_t n)const {
if (n > quantity) {
return price * quantity * discount + (n - quantity) * price;
}
else {
return n * price * discount;
}
}
Bulk_quote::Bulk_quote(const Bulk_quote& hs) {
cout << "Bulk_quote" << endl;
//Quote(hs);
}
int main() {
//Disc_quote b;
Bulk_quote a("hello", 2, 3, 0.1);
//cout << a.net_price(10) << endl;
return 0;
15.27
class Bulk_quote :public Disc_quote{
public:
using Disc_quote::Disc_quote;
Bulk_quote(const Bulk_quote&);
/*Bulk_quote() = default;
Bulk_quote(const std::string& book, double price, std::size_t qty, double disc) :Disc_quote(book, price, qty, disc) {
cout << "Bulk_qutoe constructor is running" << endl;
}*/
double net_price(std::size_t)const override;
~Bulk_quote() {
cout << "Bulk_quote destructor is running" << endl;
}
};
15.28
vector<Quote>vec;
Bulk_quote a("hello", 2, 3, 0.1);
Quote b("helli", 2);
vec.emplace_back(a);
vec.emplace_back(b);
for (auto& num : vec)cout << num.net_price(2) << endl
15.29
vector<Quote>vec;
Bulk_quote a("hello", 4, 5, 0.8);
Quote b("helli", 2);
vec.emplace_back(a);
vec.emplace_back(b);
//cout << a.net_price(2) << endl;
//cout << b.net_price(2) << endl;
for (auto& num : vec)cout << num.net_price(2) << endl;
//text
vector<shared_ptr<Quote>>vec1;
Quote* iter = &a;
cout << iter->net_price(2) << endl;
vec1.emplace_back(make_shared<Bulk_quote>("hello",4,5,0.8));
vec1.emplace_back(make_shared<Quote>("helli",2));
// cout << vec1[0]->net_price(2) << endl;
for (auto& num : vec1)cout << num->net_price(2) << endl
15.8.1节练习
15.30
#include<iostream>
#include<vector>
#include<set>
using namespace std;
class Quote
{
public:
friend class Bulk_quote;
virtual void debug() {
cout << "bookNo:" << bookNo << " price:" << price << endl;
}
virtual Quote* clone()const & { return new Quote(*this); }
virtual Quote* clone()&& { return new Quote(std::move(*this)); }
Quote(const Quote&);
Quote() = default;
Quote(const std::string& book, double sales_price) :bookNo(book), price(sales_price) {
// cout << "Quote contructor is running" << endl;
}
virtual double net_price(std::size_t n)const
{
return n * price;
}
virtual~Quote() {
// cout << "Quote destructor is running" << endl;
}
string& isbn() { return bookNo; }
private:
std::string bookNo;
protected:
double price = 0.0;
};
Quote::Quote(const Quote& rhs) {
// cout << "Quote" << endl;
bookNo = rhs.bookNo;
price = rhs.price;
}
double print_total(ostream& os, const Quote& item, size_t n)
{
double ret = item.net_price(n);
os << ret << endl;
return ret;
}
//Disc_quote
class Disc_quote :public Quote{
public:
Disc_quote() = default;
Disc_quote(const std::string& book, double price, std::size_t qty, double disc) :
Quote(book, price), quantity(qty), discount(disc) {
//cout << "Disc_quote constructor is running" << endl;
}
~Disc_quote() {
//cout << "Dis_quote destructor is running" << endl;
}
double net_price(std::size_t n)const = 0;
protected:
std::size_t quantity = 0;
double discount = 0;
};
class Bulk_quote :public Quote{
public:
void debug() { cout << "quantity:" << quantity <<" bookNo:"<<isbn()<< endl; };
Bulk_quote* clone()const& { return new Bulk_quote(*this); };
Bulk_quote* clone()&& { return new Bulk_quote(std::move(*this)); };
//using Disc_quote::Disc_quote;
Bulk_quote(const Bulk_quote&);
Bulk_quote() = default;
Bulk_quote(const std::string& book, double price, std::size_t qty, double disc) :Quote(book, price),quantity(qty),discount(disc) {
// cout << "Bulk_qutoe constructor is running" << endl;
}
double net_price(std::size_t)const override;
~Bulk_quote() {
// cout << "Bulk_quote destructor is running" << endl;
}
protected:
std::size_t quantity = 0;
double discount = 0;
};
double Bulk_quote::net_price(std::size_t n)const {
if (n > quantity) {
return price * quantity * discount + (n - quantity) * price;
}
else {
return n * price * discount;
}
}
Bulk_quote::Bulk_quote(const Bulk_quote& hs) {
price = hs.price;
bookNo = hs.bookNo;
quantity = hs.quantity;
discount = hs.discount;
}
//Basket类
class Basket {
public:
//加入
void add_item( const Quote& sale) {
// std::make_shared<Quote>(sale.clone())->debug();
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 rhs->isbn() < lhs->isbn();
}
std::multiset<std::shared_ptr<Quote>, decltype(compare)*>
items{ compare };
};
double Basket::total_receipt(std::ostream& os)const
{
double sum = 0;
for (auto iter = items.cbegin();
iter != items.cend(); iter = items.upper_bound(*iter)) {
//cout << items.count(*iter) << endl;
//(**iter).debug();
// cout << (**iter).debug() << endl;
sum += print_total(os, **iter, items.count(*iter));
// cout << sum << endl;
}
cout << "Total Sale: " << sum << endl;
return sum;
}
int main() {
//Disc_quote b;
vector<Quote>vec;
Bulk_quote a("hello", 4, 6, 0.8);
// a.clone()->debug();
Bulk_quote c("hello", 4, 7, 0.7);
Quote b("helli", 8);
//b.clone()->debug();
Quote d("helli", 9);
Basket bask;
bask.add_item(a);
bask.add_item(a);
bask.add_item(b);
bask.add_item(c);
bask.add_item(d);
bask.total_receipt(cout);//输出
return 0;
}