15.24
基类一般定义一个虚析构函数
但是虚析构函数会阻止移动操作
但是虚析构函数会帮助基类派生类体系动态销毁对象
15.25
Disc_quote定义的默认构造函数执行时会调用Quote的默认构造函数,Quote的默认构造函数则会对Quote的成员进行初始化,若是将这个默认构造函数删除,Bulk_quote是Disc_quote的子类,在它调用默认构造函数的时候会因为找不到其直接基类Disc_quote的默认构造函数而产生错误
15.26
注意虚函数继承后要有定义,不能光有声明,然后
#include <string>
#include<iostream>
#include<memory>
class Quote{
friend bool operator !=(const Quote& lhs,const Quote& rhs);
public:
Quote() = default;
Quote(const std::string &b,double p):bookNo(b),price(p){std::cout<<"两参数构造函数"<<std::endl;}
//拷贝构造函数
Quote(const Quote & rhs):bookNo(rhs.bookNo),price(rhs.price){std::cout<<"Quote的拷贝构造函数"<<std::endl;}
//移动构造函数
Quote(Quote&& q) noexcept : bookNo(std::move(q.bookNo)),price(std::move(q.price)){std::cout<<"Quote的移动构造函数"<<std::endl;}
//赋值运算符
Quote& operator=(const Quote& rhs){
if(*this != rhs){
bookNo = rhs.bookNo;
price = rhs.price;
}
std::cout<<"Quote的赋值运算符"<<std::endl;
return *this;
}
//移动赋值运算符
Quote& operator = (Quote && rhs) noexcept{
if(*this!=rhs){
bookNo = std::move(rhs.bookNo);
price = std::move(rhs.price);
}
std::cout<<"Quote的移动赋值运算符"<<std::endl;
return *this;
}
std::string isbn() const {
return bookNo;
}
virtual double net_price(std::size_t n)const{
return n*price;
}
virtual void debug() const;
virtual ~Quote(){std::cout<<"基类虚析构函数"<<std::endl;}
private:
std::string bookNo;
protected:
double price = 10.0;
};
bool inline operator != (const Quote &lhs,const Quote &rhs){
return lhs.bookNo != rhs.bookNo&&lhs.price !=rhs.price;
}
//用于保存折扣值和购买量的类,派生类使用这些数据可以实现不同的价格策略
class Disc_quote:public Quote{
public:
std::pair<std::size_t,double> discount_policy() const{
return {quantity,discount};
}
Disc_quote() = default;
Disc_quote(const std::string & book,double price,std::size_t qty,double disc):
Quote(book,price),
quantity(qty),discount(disc){}
Disc_quote(const Disc_quote&dq):Quote(dq),quantity(dq.quantity),discount(dq.discount){}
//Disc_quote(const Disc_quote&& dq):Quote(std::move(dq)),quantity(std::move(dq.quantity)),discount(std::move(dq.discount)){}
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(){std::cout<<"Bulk_quote的默认构造函数"<<std::endl;}
Bulk_quote(const std::string &b,double p,std::size_t q,double disc):Disc_quote(b,p,q,disc ){std::cout<<"Bulk_quote的四参数构造函数"<<std::endl;}
//拷贝构造函数
Bulk_quote(const Bulk_quote& bq):Disc_quote(bq){std::cout<<"Bulk_quote的拷贝构造函数"<<std::endl;}
//移动构造函数
Bulk_quote(Bulk_quote&& bq): Disc_quote(std::move(bq)) {
std::cout<<"Bulk_quote的移动构造函数"<<std::endl;
}
//赋值运算符
Bulk_quote& operator = (const Bulk_quote & rhs){
Disc_quote::operator=(rhs);
std::cout<<"Bulk_quote的赋值运算符"<<std::endl;
return*this;
}
//移动赋值运算符
Bulk_quote& operator = (Bulk_quote&& rhs) noexcept{
Disc_quote::operator=(std::move(rhs));
std::cout<<"Bulk_quote的移动赋值运算符"<<std::endl;
return*this;
}
double net_price(std::size_t) const override;
void debug() const override;
~Bulk_quote() override{std::cout<<"Bulk_quote的析构"<<std::endl;}
};
使用的main函数
#include <iostream>
#include"Base.h"
#include<memory>
#include<vector>
int main(){
std::vector<Quote> backet;
backet.push_back(Quote("0-201-82448-1",50));
backet.push_back(Bulk_quote("0-201-54848-8",50,10,.25));
//注释解释上传的运行结果的执行过程,稍微有点绕
//构造一个Quote的对象 Q双参
//使用Quoete的移动构造函数将刚才生成的Quote对象移动到vector中 Q移动构造,就不用Q的双参数构造了
//被移动的对象销毁 析构
//先Q的双参数构造,再Bulk_quote的四参数构造
//Bulk_quote切掉派生类部分,这个过程使用了Quote的移动构造
//在vector中又将切完的Quote对象移动构造过来
//切完的Quote移动完执行析构
//Bulk_quote的析构--先派生析构,再基类析构
//程序完成,最后再将vector里面的两个Quote对象析构
return 0;
}
运行结果
image.png
15.27
要继承Disc_quote的构造函数
只需要加上
using Disc_quote::Disc_quote;
就能获得Disc_quote类的所有构造函数的继承
15.28and15.29
29题使用智能指针,并不会把基类之外的内容切掉,也就是保留了net_price函数的Bulk_quote版本,所以调用net_price的时候实际上是调用的Bulk_quote的版本
#include <iostream>
#include"Base.h"
#include<memory>
#include<vector>
int main(){
//15.28
std::vector<Quote> vec;
for (int i = 1; i != 3; ++i)
vec.push_back(Bulk_quote("sss", i * 10, 10, 0.3));
double total = 0;
for (const auto& b : vec)
{
total += b.net_price(1);
}
std::cout << total << std::endl;
std::cout << "======================"<<std::endl;
//15.29
std::vector<std::shared_ptr<Quote>> pvec;
for (int i = 1; i != 3; ++i)
pvec.push_back(std::make_shared<Bulk_quote>(Bulk_quote("sss", i * 10, 1, 0.3)));
double total_p = 0;
for (auto p : pvec)
{
total_p += p->net_price(1);
}
std::cout << total_p << std::endl;
return 0;
}
网友评论