c++ primer 第十五章習題
阿新 • • 發佈:2018-11-08
c++ primer 第十五章習題
練習15.1 派生類需要覆蓋的基類中的virtual成員
練習15.2 protected訪問符定義的成員可以被繼承類的成員函式及友元訪問,private只能被當前類的成員和友元訪問。
練習15.3
class Quote { public: Quote() = default; Quote(const string& book, double sales_price): bookNo(book), price(sales_price) {} string isbn() const { return bookNo;} virtual double net_price(size_t n) const { return n*price; } virtual ~Quote() = default; private: string bookNo; protected: double price = 0.0; }; double print_total(ostream &os, const Quote &item, size_t n) { double ret = item.net_price(n); os << "ISBN: "<<item.isbn() << " # sold: " << n << " total due: " << ret << endl; return ret; }
練習15.4 (a) 不能繼承自己,是定義不是宣告。 (b) 是定義不是宣告。 ©不需要加繼承關係。
練習15.5
class Bulk_quote:public Quote { public: Bulk_quote(const string& book, double p, size_t qty, double disc): Quote(book,p),min_qty(qty),discount(disc) {} double net_price(size_t n) const override { if(n >= min_qty) return n*(1-discount)*price; else return n*price; } private: int min_qty; double discount; };
練習15.7
class Disc_quote:public Quote { public: Disc_quote(const string& book, double p, size_t qty, double disc): Quote(book,p),max_qty(qty),discount(disc) {} double net_price(size_t n) const override { if(n <= max_qty) return n*(1-discount)*price; else return (n-max_qty)*price+max_qty*(1-discount)*price; } private: int max_qty; double discount; };
練習15.8 靜態型別是指編譯時已知的,變數宣告時的型別或者表示式生成的型別。動態型別是指變數或表示式表示的記憶體中的物件的型別,執行時才知道。
練習15.9 使用基類指標或者引用時。
練習15.12 有必要,兩個功能不影響。
練習15.13 有問題,派生類裡呼叫base::print
練習15.14 (a) base (b) derived © base (d) base (e) base (f) derived
練習15.15
class Disc_quote:public Quote
{
public:
Disc_quote(const string& book, double p, size_t qty, double disc):
Quote(book,p),quantity(qty),discount(disc) {}
double net_price(size_t n) const = 0;
protected:
size_t quantity = 0;
double discount = 0.0;
};
class Bulk_quote:public Disc_quote
{
public:
Bulk_quote(const string& book, double p, size_t qty, double disc):
Disc_quote(book,p,qty,disc){}
double net_price(size_t n) const override {
if(n >= quantity)
return n*(1-discount)*price;
else
return n*price;
}
};
練習15.16
class Max_quote:public Disc_quote
{
public:
Max_quote(const string& book, double p, size_t qty, double disc):
Disc_quote(book,p,qty,disc){}
double net_price(size_t n) const override {
if(n >= quantity)
return quantity*(1-discount)*price + (n-quantity)*price;
else
return n*(1-discount)*price;
}
};
練習15.18 T F 不能訪問base公有成員 F同上 T F F
練習15.19 TTTTFT
練習15.23 加個定義;除了bp2->fcn()其它不變。
練習15.24 有繼承類的基類
練習15.25 因為Disc_quote的預設建構函式會執行Quote的預設建構函式,而Quote預設建構函式會完成成員的初始化工作。 如果去除掉該建構函式的話,Bulk_quote的預設建構函式而無法完成Disc_quote的初始化工作。(因為不定義的話在已有建構函式的情況下不會再合成預設建構函式)
練習15.26
#ifndef MYQUOTE_H
#define MYQUOTE_H
#include <iostream>
#include <vector>
#include <string>
#include <memory>
using namespace std;
class Quote {
public:
Quote() = default;
friend bool operator !=(const Quote& lhs, const Quote& rhs);
Quote(const string& book, double sales_price):
bookNo(book), price(sales_price) {}
Quote(const Quote& q):bookNo(q.bookNo),price(q.price){
cout << "Quote(Quote& q)"<<endl;
}
Quote(Quote&& q) noexcept:bookNo(move(q.bookNo)),price(move(q.price)){
cout << "Quote(Quote&& q)"<<endl;
}
Quote& operator=(const Quote& q) {
if(q != *this) {
bookNo = q.bookNo;
price = q.price;
}
cout << "Quote& operator=(Quote& q)"<<endl;
return *this;
}
Quote& operator=(Quote&& q) noexcept {
if(q != *this) {
bookNo = move(q.bookNo);
price = move(q.price);
}
cout << "Quote& operator=(Quote&& q)"<<endl;
return *this;
}
string isbn() const { return bookNo;}
virtual double net_price(size_t n) const {
cout << "Quote::net_price"<<endl;
return n*price;
}
virtual Quote* clone() const &{
return new Quote(*this);
}
virtual Quote* clone() &&{
return new Quote(move(*this));
}
virtual void debug() const{
cout << "bookNo: "<< bookNo << " price: " << price << endl;
}
virtual ~Quote() = default;
private:
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 <iostream>
#include <vector>
#include <string>
#include <memory>
#include "myQuote.h"
using namespace std;
class Disc_quote:public Quote
{
friend bool operator!=(const Disc_quote&, const Disc_quote&);
public:
Disc_quote() {
cout << "Disc_quote()" <<endl;
}
Disc_quote(const string& book, double p, size_t qty, double disc):
Quote(book,p),quantity(qty),discount(disc) {}
Disc_quote(const Disc_quote& dq):
Quote(dq.isbn(),dq.price),quantity(dq.quantity),discount(dq.discount){}
Disc_quote(Disc_quote&& dq) noexcept:
Quote(dq.isbn(),move(dq.price)),quantity(move(dq.quantity)),discount(move(dq.discount)){}
Disc_quote& operator=(const Disc_quote& dq) {
if(*this != dq) {
Quote(dq.isbn(), dq.price);
quantity = dq.quantity;
discount = dq.discount;
}
cout << "Disc_quote& operator=(const Disc_quote& dq)" <<endl;
return *this;
}
Disc_quote& operator=(Disc_quote&& dq) noexcept{
if(*this != dq) {
Quote(dq.isbn(), move(dq.price));
quantity = move(dq.quantity);
discount = move(dq.discount);
}
cout << "Disc_quote& operator=(Disc_quote&& dq)" <<endl;
return *this;
}
~Disc_quote() {
cout << "~Disc_quote()"<<endl;
}
double net_price(size_t n) const = 0;
protected:
size_t quantity = 0;
double discount = 0.0;
};
bool inline
operator !=(const Disc_quote& lhs, const Disc_quote& rhs)
{
return lhs.isbn() != rhs.isbn()||lhs.price != rhs.price
||lhs.quantity != rhs.quantity || lhs.discount != rhs.discount;
}
#endif
#ifndef BULK_QUOTE_H
#define BULK_QUOTE_H
#include <iostream>
#include <vector>
#include <string>
#include <memory>
#include "Disc_quote.h"
using namespace std;
class Bulk_quote : public Disc_quote
{
public:
Bulk_quote() { std::cout << "default constructing Bulk_quote\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) noexcept: Disc_quote(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) noexcept
{
Disc_quote::operator =(std::move(rhs));
std::cout << "Bulk_quote : move =()\n";
return *this;
}
double net_price(std::size_t n) const override{
cout << "Bulk_quote::net_price"<<endl;
if(n >= quantity)
return n*(1-discount)*price;
else
return n*price;
};
Quote* clone() const & override {
return new Bulk_quote(*this);
}
Quote* clone() && override {
return new Bulk_quote(move(*this));
}
void debug() const override{
cout << "Bulk_quote::debug(): ";
cout << "bookNo: "<< isbn() << " price: " << price <<"quantity: " << quantity<< "discount: "<<discount<< endl;
};
~Bulk_quote()
{
cout << "destructing Bulk_quote" <<endl;
}
};
double print_total(ostream &os, const Quote &item, size_t n) {
double ret = item.net_price(n);
os << "ISBN: "<<item.isbn() << " # sold: " << n << " total due: " << ret << endl;
return ret;
}
#endif
練習15.28 29
int main() {
Bulk_quote bq("0-3843-3432",3.4, 5, 0.1);
Bulk_quote bq2("0-3843-3432",3.2, 15, 0.2);
vector<Quote> v1 = {bq,bq2};
vector<shared_ptr<Quote>> v2 = {make_shared<Bulk_quote>(bq), make_shared<Bulk_quote>(bq2)};
double res = 0;
res = v1[0].net_price(20)+v1[1].net_price(20);
cout << "vector<Quote> total price: "<< res<<endl;
res = v2[0]->net_price(20)+v2[1]->net_price(20);
cout << "vector<make_shared<Quote>> total price: "<< res<<endl;
return 0;
}
練習15.30
#ifndef MYBASKET_H
#define MYBASKET_H
#include "Bulk_quote.h"
#include <set>
class basket
{
public:
void add_item(Quote&& sale) {
items.insert(shared_ptr<Quote>(move(sale).clone()));
}
void add_item(const Quote& sale) {
items.insert(shared_ptr<Quote>(sale.clone()));
}
double total_receipt(ostream& os) const {
double sum = 0;
for(auto iter = items.begin(); iter != items.end(); iter = items.upper_bound(*iter)) {
sum += print_total(os,**iter,items.count(*iter));
}
os << "Total Sale: " << sum <<endl;
return sum;
}
private:
bool static compare(const shared_ptr<Quote>& a, const shared_ptr<Quote>& b) {
return a->isbn() < b->isbn();
}
multiset<shared_ptr<Quote>,decltype(compare)*> items{compare};
};
#endif
int main() {
Bulk_quote bq("0-3843-3432",3.4, 5, 0.1);
Bulk_quote bq2("0-3843-3432",3.2, 15, 0.2);
basket bs;
bs.add_item(bq);
bs.add_item(bq2);
bs.total_receipt(cout);
return 0;
}