Quote.h
#ifndef _QUOTE_H_ #define _QUOTE_H_ #include<iostream> #include<string> class Quote{ friend bool operator !=(const Quote &lhs, const Quote &rhs); public: Quote(){ std::cout << "default constructing Quote.\n"; } Quote(const std::string &b, const double p) : bookNo(b), price(p){std::cout << "Quote:constructor taking 2 parameters\n ";} //copy constructor Quote(const Quote &q) :bookNo(q.bookNo), price(q.price){ std::cout << "Quote:copy constructor!\n"; } //move constructor Quote(Quote &q) :bookNo(std::move(q.bookNo)), price(std::move(q.price)) {std::cout << "Quote : move constructor!\n";} //copy = Quote & operator=(const Quote & rhs) { if (*this != rhs) { bookNo = rhs.bookNo; price = rhs.price; } std::cout << "Quote:copy = () \n"; return *this; } //move = /*Quote & operator=(Quote & rhs) noexcept //VS2013不支持该关键字 { if (*this != rhs) { bookNo = std::move(rhs.bookNo); price = std::move(rhs.price); } std::cout << "Quote:move = !!!!!!!!!!!\n"; return *this; }*/ std::string isbn(){ return bookNo; } virtual double net_price(std::size_t n) const { return n*price; } virtual void debug() const{ std::cout << "data membets of this class:\n" << "bookNo = " << bookNo << " " << "price = " << price << "\n"; } virtual ~Quote() { std::cout << "destructing Quote\n"; } private: std::string bookNo; protected: double price = 0.0; }; bool inline operator !=(const Quote &lhs, const Quote &rhs) { return lhs.bookNo != rhs.bookNo && lhs.price != rhs.price; } #endif
#ifndef _DISC_QUOTE_H_ #define _DISC_QUOTE_H_ #include"Quote.h" class Disc_quote :public Quote{ friend bool operator!=(const Disc_quote &lhs, const Disc_quote &rhs); public: Disc_quote(){ std::cout << "default constructor Disc_Quote\n"; } Disc_quote(const std::string &b, double p, std::size_t q, double d) : Quote(b, p), quantity(q), discount(d) {std::cout << "Disc_quote: constructor taking 4 parameters.\n";} //copy Disc_quote(const Disc_quote & dq) :Quote(dq), quantity(dq.quantity), discount(dq.discount) {std::cout << "Disc_quote: copy constructor.\n";} //move Disc_quote(Disc_quote &dq) :Quote(std::move(dq)), quantity(std::move(dq.quantity)), discount(std::move(dq.discount)) {std::cout << "Disc_quote: move constructor.\n";} //! copy =() Disc_quote& operator =(const Disc_quote& rhs) { Quote::operator =(rhs); this->quantity = rhs.quantity; this->discount = rhs.discount; std::cout << "Disc_quote : copy =()\n"; return *this; } //! move =() /*Disc_quote& operator =(Disc_quote&& rhs) { if (*this != rhs) { Quote::operator =(std::move(rhs)); this->quantity = std::move(rhs.quantity); this->discount = std::move(rhs.discount); } std::cout << "Disc_quote : move =()\n"; return *this; }*/ virtual double net_price(std::size_t n) const override = 0; ~Disc_quote() { std::cout << "destructing Dis_quote\n"; } protected: std::size_t quantity = 3; double discount = 0.0; }; bool inline operator !=(const Disc_quote& lhs, const Disc_quote& rhs) { return Quote(lhs) != Quote(rhs) && lhs.quantity != rhs.quantity && lhs.discount != rhs.discount; } #endif
#ifndef BULK_QUOTE_H #define BULK_QUOTE_H #include "disc_quote.h" class Bulk_quote : public Disc_quote { public: Bulk_quote() { std::cout << "default constructing Bulk_quote\n"; } Bulk_quote(const std::string &b, double p, std::size_t q, double d): Disc_quote(b, p, q, d){ std::cout << "Bulk_quote:4 parameters in constructor.\n"; } //! changed the below to the inherited constructor for ex15.27. //! rules: 1. only inherit from the direct base class. //! 2. default,copy and move constructors can not inherit. //! 3. any data members of its own are default initialized. //! 4. the rest details are in the section section 15.7.4. /* Bulk_quote(const std::string& b, double p, std::size_t q, double disc) : Disc_quote(b,p,q,disc) { std::cout << "Bulk_quote : constructor taking 4 parameters\n"; } */ using Disc_quote::Disc_quote; //! copy constructor Bulk_quote(const Bulk_quote& bq) : Disc_quote(bq) { std::cout << "Bulk_quote : copy constructor\n"; } //! move constructor Bulk_quote(Bulk_quote&& bq) : Disc_quote(std::move(bq)) { std::cout << "Bulk_quote : move constructor\n"; } //! copy =() Bulk_quote& operator =(const Bulk_quote& rhs) { Disc_quote::operator =(rhs); std::cout << "Bulk_quote : copy =()\n"; return *this; } //! move =() Bulk_quote& operator =(Bulk_quote&& rhs) { Disc_quote::operator =(std::move(rhs)); std::cout << "Bulk_quote : move =()\n"; return *this; } double net_price(std::size_t n) const override; void debug() const override; ~Bulk_quote() override { std::cout << "destructing Bulk_quote\n"; } }; double Bulk_quote::net_price(std::size_t n) const { return n * price * (n >= quantity ? 1 - discount : 1); } void Bulk_quote::debug() const { std::cout //<< "data members of this class:\n" << "min_qty= " << quantity << " " << "discount= " << this->discount << " \n"; } #endif // BULK_QUOTE_H
#ifndef LIMIT_QUOTE_H #define LIMIT_QUOTE_H #include "disc_quote.h" class Limit_quote : public Disc_quote { public: Limit_quote() = default; Limit_quote(const std::string& b, double p, std::size_t max, double disc) : Disc_quote(b, p, max, disc) { } double net_price(std::size_t n) const override { return n * price * (n < quantity ? 1 - discount : 1); } void debug() const override { std::cout //<< "data members of this class:\n" << "max_qty= " << this->quantity << " " << "discount= " << this->discount << " \n"; } }; #endif // LIMIT_QUOTE_H
//! Exercise 15.28: //! Define a vector to hold Quote objects but put Bulk_quote objects into that //! vector. Compute the total net_price of all the elements in the vector. //! //! Exercise 15.29: //! Repeat your program, but this time store shared_ptrs to objects of type //! Quote. Explain any discrepancy in the sum generated by the this version and //! the previous program. //! // Since the vector from the previous exercise holds objects, there's no polymorphism // happened while calling the virtual function net_price. Essentially, the obejcts // held in it are the Quote subjects of the Bulk_quote objects being pushed back, // Thus, the virtual net_price functions called are Quote::net_price. As a result, // no discount was applied. The outcome was 9090 // // The obejcts held for this exercise are smart pointers to the Quote objects.In this // case, ppolymorphism happened as expected.The actual virtual functions being called // are Bulk_quote::net_price that ensure discount is applied.Thus, the outcome is 6363. // It can be found that 30% dicount has been applied to the price calculation. // //! //! If there is no discrepancy, explain why there isn’t one. //! #include <iostream> #include <string> #include <vector> #include <memory> #include "quote.h" #include "bulk_quote.h" #include "limit_quote.h" #include "disc_quote.h" int main() { /** * @brief ex15.28 outcome == 9090 */ std::vector<Quote> v; for (unsigned i = 1; i != 3; ++i) v.push_back(Bulk_quote("sss", i * 10.1, 10, 0.3)); std::cout << "======================\n\n"; double total = 0; for (const auto& b : v) { total += b.net_price(20); } std::cout << total << std::endl; std::cout << "======================\n\n"; /** * @brief ex15.29 outccome == 6363 */ std::vector<std::shared_ptr<Quote>> pv; for (unsigned i = 1; i != 3; ++i) pv.push_back(std::make_shared<Bulk_quote>(Bulk_quote("sss", i * 10.1, 10, 0.3))); std::cout << "======================\n\n"; double total_p = 0; for (auto p : pv) { total_p += p->net_price(20); } std::cout << total_p << std::endl; system("pause"); return 0; }
Quote:constructor taking 2 parameters Disc_quote: constructor taking 4 parameters. Bulk_quote:4 parameters in constructor. Quote:copy constructor! destructing Bulk_quote destructing Dis_quote destructing Quote Quote:constructor taking 2 parameters Disc_quote: constructor taking 4 parameters. Bulk_quote:4 parameters in constructor. Quote:copy constructor! destructing Quote Quote:copy constructor! destructing Bulk_quote destructing Dis_quote destructing Quote ====================== 606 ====================== Quote:constructor taking 2 parameters Disc_quote: constructor taking 4 parameters. Bulk_quote:4 parameters in constructor. Quote:copy constructor! Disc_quote: copy constructor. Bulk_quote : move constructor destructing Bulk_quote destructing Dis_quote destructing Quote Quote:constructor taking 2 parameters Disc_quote: constructor taking 4 parameters. Bulk_quote:4 parameters in constructor. Quote:copy constructor! Disc_quote: copy constructor. Bulk_quote : move constructor destructing Bulk_quote destructing Dis_quote destructing Quote ====================== 424.2 请按任意键继续. . .