c++primer 15.24-15.30

2019-07-12  本文已影响0人  青吟乐

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;
}
上一篇下一篇

猜你喜欢

热点阅读