C++ - 面向对象(继承、虚函数和抽象基类)

基类 Quote,定义图书的编号和价格

    // Quote
    class Quote {
    public:
        Quote() = default;

        Quote(const string &book, double salesPrice) : bookNo(book), price(salesPrice) {}

        // 拷贝/移动控制成员
        Quote(const Quote &other) : bookNo(other.bookNo), price(other.price) {}

        Quote(Quote &&other) : bookNo(std::move(other.bookNo)), price(std::move(other.price)) {}

        Quote &operator=(const Quote &rhs);

        Quote &operator=(Quote &&rhs);

        string isbn() const { return bookNo; }

        virtual double netPrice(std::size_t n) const { return n * price; }  // 购买n本图书的花费

        virtual ostream &debugPrint(ostream &os) const; // 打印成员信息

        virtual ~Quote() = default;

    private:
        string bookNo; // 图书编号
    protected:
        double price = 0.0;  // 价格,protected 访问类型标识派生类可以访问但是其他类不行
    };

    // 成员实现
    ostream &Quote::debugPrint(ostream &os) const {
        os << "ISBN: " << bookNo << ", price: " << price;
        return os;
    }

   Quote &Quote::operator=(const Quote &rhs) {
        if (this == &rhs) {
            return *this;
        }
        bookNo = rhs.bookNo;
        price = rhs.price;
        return *this;
    }

    Quote &Quote::operator=(Quote &&rhs) {
        if (this == &rhs) {
            return *this;
        }
        bookNo = std::move(rhs.bookNo);
        price = std::move(rhs.price);
        return *this;
    }
    
    // 公共函数,打印给定图书购买n本的花费
    // COMMON DEBUG_PRINT
    double printTotal(ostream &os, Quote &item, std::size_t n) {
        double ret = item.netPrice(n);
        os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret << endl;
        return ret;
    }

子类 DisQuote,折扣基类,定义折扣需要的数量和折扣优惠(优惠是超过数量或者小于数量等在派生类中根据业务确定)

    // DisQuote 折扣基类,定义折扣需要的数量和折扣优惠(优惠是超过数量或者小于数量等在派生类中根据业务确定)
    class DisQuote : public Quote {
    public:
        DisQuote() = default;

        DisQuote(const string &book, double price, std::size_t qty, double disc) : Quote(book, price), quantity(qty),
                                                                                   discount(disc) {}

        // 拷贝/移动控制成员
        DisQuote(const DisQuote &other) : Quote(other), quantity(other.quantity), discount(other.discount) {}

        DisQuote(DisQuote &&other) : Quote(std::move(other)), quantity(std::move(other.quantity)),
                                     discount(std::move(other.discount)) {}

        DisQuote &operator=(const DisQuote &rhs);

        DisQuote &operator=(DisQuote &&rhs);

        virtual double netPrice(std::size_t n) const = 0;  //  纯虚函数

        virtual ostream &debugPrint(ostream &os) const override; // 打印成员信息

    protected:
        std::size_t quantity = 0;
        double discount = 0.0;
    };

    
    // 成员实现
    ostream &DisQuote::debugPrint(ostream &os) const {
        os << "ISBN: " << isbn() << ", price: " << price << ", quantity: " << quantity << ", discount: " << discount;
        return os;
    }

    DisQuote &DisQuote::operator=(const DisQuote &rhs) {
        if (this == &rhs) {
            return *this;
        }
        Quote::operator=(rhs);
        quantity = rhs.quantity;
        discount = rhs.discount;
        return *this;
    }

    DisQuote &DisQuote::operator=(DisQuote &&rhs) {
        if (this == &rhs) {
            return *this;
        }
        Quote::operator=(std::move(rhs));
        quantity = std::move(rhs.quantity);
        discount = std::move(rhs.discount);
        return *this;
    }

子类 BulkQuote ,大于给定数量才有折扣优惠,否则按照原价计算

    // BulkQuote 大于给定数量才有折扣优惠,否则按照原件计算
    class BulkQuote : public DisQuote {
    public:
        BulkQuote() = default;

//        BulkQuote(const string &book, double price, std::size_t qty, double disc) : DisQuote(book, price, qty, disc) {}

        using DisQuote::DisQuote; // "继承"直接基类的构造函数


        // 拷贝/移动控制成员
        BulkQuote(const BulkQuote &other) : DisQuote(other) { cout << "BulkQuote copy construct" << endl; }

        BulkQuote(BulkQuote &&other) : DisQuote(std::move(other)) { cout << "BulkQuote move construct" << endl; }

        BulkQuote &operator=(const BulkQuote &rhs);

        BulkQuote &operator=(BulkQuote &&rhs);

        virtual double netPrice(std::size_t n) const override;

        virtual ostream &debugPrint(ostream &os) const override; // 打印成员信息
    };

    
    // 成员实现
    double BulkQuote::netPrice(std::size_t n) const {
        if (n >= quantity) {
            return n * (1 - discount) * price;
        } else {
            return Quote::netPrice(n);
        }
    }

    ostream &BulkQuote::debugPrint(ostream &os) const {
        DisQuote::debugPrint(os);
        return os;
    }

    BulkQuote &BulkQuote::operator=(const BulkQuote &rhs) {
        cout << "BulkQuote copy assignment" << endl;
        if (this == &rhs) {
            return *this;
        }
        DisQuote::operator=(rhs);
        return *this;
    }

    BulkQuote &BulkQuote::operator=(BulkQuote &&rhs) {
        cout << "BulkQuote move assignment" << endl;
        if (this == &rhs) {
            return *this;
        }
        DisQuote::operator=(std::move(rhs));
        return *this;
    }

子类 SlightQuote, 小于给定数量的部分有折扣优惠,超过部分按照原价计算

    // BulkQuote 小于给定数量的部分有折扣优惠,超过部分按照原件计算
    class SlightQuote : public DisQuote {
    public:
        SlightQuote() = default;

//        SlightQuote(const string &book, double price, std::size_t qty, double disc) : DisQuote(book, price, qty,
//                                                                                               disc) {}

        using DisQuote::DisQuote; // "继承"直接基类的构造函数

        // 拷贝/移动控制成员
        SlightQuote(const SlightQuote &other) : DisQuote(other) { cout << "SlightQuote copy construct" << endl; }

        SlightQuote(SlightQuote &&other) : DisQuote(std::move(other)) { cout << "SlightQuote move construct" << endl; }

        SlightQuote &operator=(const SlightQuote &rhs);

        SlightQuote &operator=(SlightQuote &&rhs);

        virtual double netPrice(std::size_t n) const override;

        virtual ostream &debugPrint(ostream &os) const override; // 打印成员信息
    };


    // 成员实现
    double SlightQuote::netPrice(std::size_t n) const {
        std::size_t exceedNum = n - quantity;
        if (exceedNum < 0) {
            return n * (1 - discount) * price;
        } else {
            // quantity * (1 - discount) * price + exceedNum * price;
            return price * (n - quantity * discount);
        }
    }

    ostream &SlightQuote::debugPrint(ostream &os) const {
        DisQuote::debugPrint(os);
        return os;
    }

    SlightQuote &SlightQuote::operator=(const SlightQuote &rhs) {
        cout << "SlightQuote copy assignment" << endl;
        if (this == &rhs) {
            return *this;
        }
        DisQuote::operator=(rhs);
        return *this;
    }

    SlightQuote &SlightQuote::operator=(SlightQuote &&rhs) {
        cout << "SlightQuote move assignment" << endl;
        if (this == &rhs) {
            return *this;
        }
        DisQuote::operator=(std::move(rhs));
        return *this;
    }

测试代码:

    // Quote测试
    void MyQuoteTest() {
        // Quote
        MyQuoteSpace::Quote qt1("099-120-321", 20);
        MyQuoteSpace::printTotal(cout, qt1, 20);

        // BulkQuote
        MyQuoteSpace::BulkQuote bqt1("099-120-321", 20, 10, 0.1);
        MyQuoteSpace::BulkQuote bqt2("099-120-321", 20, 5, .19);
        MyQuoteSpace::printTotal(cout, bqt1, 20);
        MyQuoteSpace::printTotal(cout, bqt1, 10);

        cout << endl;
        MyQuoteSpace::Quote *pqt1 = &qt1, *pqt2 = &bqt1, *pqt3 = &bqt2;
        pqt1->debugPrint(cout) << endl;
        pqt2->debugPrint(cout) << endl;
        pqt3->debugPrint(cout) << endl;

        // SlightQuote
//        MyQuoteSpace::DisQuote disquote;  // 错误,不能定义抽象基类的对象

        cout << endl;
        MyQuoteSpace::Quote qt2("099-120-322", 40);
        MyQuoteSpace::printTotal(cout, qt2, 20);

        MyQuoteSpace::SlightQuote sqt1("099-120-322", 40, 10, 0.1);
        MyQuoteSpace::SlightQuote sqt2("099-120-322", 40, 5, .19);
        MyQuoteSpace::printTotal(cout, sqt1, 20);
        MyQuoteSpace::printTotal(cout, sqt2, 4);

        // 拷贝/移动控制测试
        MyQuoteSpace::BulkQuote bqt3 = bqt1;
        MyQuoteSpace::BulkQuote bqt4 = std::move(bqt3);
        bqt4 = bqt1;
        bqt4 = std::move(bqt2);

        MyQuoteSpace::SlightQuote sqt3 = sqt1;
        MyQuoteSpace::SlightQuote sqt4 = std::move(sqt3);
        sqt4 = sqt1;
        sqt4 = std::move(sqt2);

        return;
    }

调试结果

参考 C++ Primer 第五版 第15章

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值