美文网首页
c++primer 15.24-15.30

c++primer 15.24-15.30

作者: 青吟乐 | 来源:发表于2019-07-12 21:07 被阅读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;
    }
    

    相关文章

      网友评论

          本文标题:c++primer 15.24-15.30

          本文链接:https://www.haomeiwen.com/subject/mpdjkctx.html