15.1
基类需要其派生类继承的成员;
15.2
派生类成员函数有权访问基类中protected成员,而无权访问privated成员;
15.3
#include<iostream>
#include<string>
class Quote
{
public:
Quote() = default;
Quote(const std::string& book, double sales_price) :bookNo(book),price(sales_price) {}
std::string isbn() const { return bookNo; }
virtual double net_price(std::size_t n)const { return n * price; }
virtual ~Quote() = default;
private:
std::string bookNo;
protected:
double price = 0.0;
};
double print_total(std::ostream& os, const Quote& item, size_t n)
{
double ret = item.net_price(n);
os << "ISBN: " << item.isbn() << " #sold " << n << " total due: " << ret << std::endl;
return ret;
}
int main()
{
Quote q("a1", 80);
print_total(std::cout, q, 2);
}
15.4
a)不正确,是定义,不是声明,而且不能继承自己;
b)不正确,是定义,不是声明;
c)不正确,声明中包含类名但不包含它的派生列表;
15.5
#include<iostream>
#include<string>
class Quote
{
public:
Quote() = default;
Quote(const std::string& book, double sales_price) :bookNo(book),price(sales_price) {}
std::string isbn() const { return bookNo; }
virtual double net_price(std::size_t n)const { return n * price; }
virtual ~Quote() = default;
private:
std::string bookNo;
protected:
double price = 0.0;
};
class Bulk_Quote :public Quote
{
public:
Bulk_Quote() = default;
Bulk_Quote(const std::string& book, double p, std::size_t qty, double disc) :Quote(book,p),min_qty(qty),discount(disc) {}
double net_price(std::size_t)const override;
private:
std::size_t min_qty = 0;
double discount = 0.0;
};
double print_total(std::ostream& os, const Quote& item, size_t n)
{
double ret = item.net_price(n);
os << "ISBN: " << item.isbn() << " #sold " << n << " total due: " << ret << std::endl;
return ret;
}
double Bulk_Quote::net_price(size_t cnt)const
{
if (cnt > min_qty) return cnt * (1 - discount) * price;
else return cnt * price;
}
int main()
{
Quote q("a1", 80);
print_total(std::cout, q, 2);
Bulk_Quote bq("a2", 80, 5, 0.2);
print_total(std::cout, bq, 10);
}
15.6
#include<iostream>
#include<string>
class Quote
{
public:
Quote() = default;
Quote(const std::string& book, double sales_price) :bookNo(book),price(sales_price) {}
std::string isbn() const { return bookNo; }
virtual double net_price(std::size_t n)const { return n * price; }
virtual ~Quote() = default;
private:
std::string bookNo;
protected:
double price = 0.0;
};
class Bulk_Quote :public Quote
{
public:
Bulk_Quote() = default;
Bulk_Quote(const std::string& book, double p, std::size_t qty, double disc) :Quote(book,p),min_qty(qty),discount(disc) {}
double net_price(std::size_t)const override;
private:
std::size_t min_qty = 0;
double discount = 0.0;
};
double print_total(std::ostream& os, const Quote& item, size_t n)
{
double ret = item.net_price(n);
os << "ISBN: " << item.isbn() << " #sold " << n << " total due: " << ret << std::endl;
return ret;
}
double Bulk_Quote::net_price(size_t cnt)const
{
if (cnt > min_qty) return cnt * (1 - discount) * price;
else return cnt * price;
}
int main()
{
Quote q("a1", 80);
print_total(std::cout, q, 2);
Bulk_Quote bq("a2", 80, 5, 0.2);
print_total(std::cout, bq, 10);
}
15.7
#include<iostream>
#include<string>
class Quote
{
public:
Quote() = default;
Quote(const std::string& book, double sales_price) :bookNo(book),price(sales_price) {}
std::string isbn() const { return bookNo; }
virtual double net_price(std::size_t n)const { return n * price; }
virtual ~Quote() = default;
private:
std::string bookNo;
protected:
double price = 0.0;
};
class Limit_Quote :public Quote
{
public:
Limit_Quote() = default;
Limit_Quote(const std::string& book, double p, std::size_t qty, double disc) :Quote(book,p),max_qty(qty),discount(disc) {}
double net_price(std::size_t)const override;
private:
std::size_t max_qty = 0;
double discount = 0.0;
};
double print_total(std::ostream& os, const Quote& item, size_t n)
{
double ret = item.net_price(n);
os << "ISBN: " << item.isbn() << " #sold " << n << " total due: " << ret << std::endl;
return ret;
}
double Limit_Quote::net_price(size_t cnt)const
{
if (cnt <= max_qty)return cnt * (1 - discount) * price;
else return max_qty * (1 - discount) * price + (cnt - max_qty) * price;
}
int main()
{
Quote q("a1", 80);
print_total(std::cout, q, 2);
Limit_Quote bq("a2", 80, 5, 0.2);
print_total(std::cout, bq, 10);
}
15.9
Bulk_quote bulk_quote("bulk_quote_1", 10.10, 10, 0.5);
// The pointer is of static type Quote, but it's dynamic type is Bulk Quote
// Because of polymorphism the Bulk Quote implementation of the net_price()
// method gets called.
Quote *quote_pointer = &bulk_quote;
quote_pointer->net_price(5);
// The reference is of static type Quote, but it's dynamic type is Bulk Quote
// Like with the pointer, the Bulk Quote implementation of the net_price()
// method gets called.
Quote "e_reference = bulk_quote;
quote_reference.net_price(5);
// The static type of this variable is Quote. Here the Bulk Quote object
// gets upcasted. The Quote part of bulk_quote gets copied into quote, but
// the rest is not handled. Because of the cast the Quote implementation of
// the net_price() method gets called.
Quote quote = bulk_quote;
quote.net_price(5);
15.11
Quote.h
#ifndef QUOTE_H_
#define QUOTE_H_
#include <string>
#include <iostream>
class Quote
{
public:
Quote() = default;
Quote(const std::string& book, double sales_price) : bookNo(book), price(sales_price) {}
std::string isbn() const { return bookNo; }
virtual double net_price(std::size_t n) const { return n * price; }
virtual void debug() const;
virtual ~Quote() = default;
private:
std::string bookNo;
protected:
double price = 0;
};
void Quote::debug() const
{
std::cout << "bookNo: " << bookNo
<< "; price: " << price;
}
#endif
Bulk_Quote.h
#ifndef BULK_QUOTE_H_
#define BULK_QUOTE_H_
#include "Quote.h"
#include <string>
#include <iostream>
class Bulk_quote : public Quote
{
public:
Bulk_quote() = default;
Bulk_quote(const std::string& book, double p, std::size_t qty, double disc) : Quote(book, p), min_qty(qty), discount(disc) { }
double net_price(std::size_t) const override;
void debug() const override;
private:
std::size_t min_qty = 0;
double discount = 0.0;
};
double Bulk_quote::net_price(size_t cnt) const
{
if (cnt >= min_qty) return cnt * (1 - discount) * price;
else return cnt * price;
}
void Bulk_quote::debug() const
{
Quote::debug();
std::cout << "; min_qty: " << min_qty
<< "; discount: " << discount;
}
#endif
test.cpp
#include"Quote.h"
#include"Bulk_Quote.h"
#include <iostream>
#include <functional>
double print_total(std::ostream& os, const Quote& item, size_t n)
{
double ret = item.net_price(n);
os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret << std::endl;
return ret;
}
int main()
{
Quote q("A1-001", 80);
Bulk_quote bq("A1-001", 80, 5, 0.2);
// print_total(std::cout, q, 10);
// print_total(std::cout, bq, 10);
q.debug();
std::cout << std::endl;
bq.debug();
std::cout << std::endl;
return 0;
}
15.15
Disc_quote.h
#ifndef DISC_QUOTE_
#define DISC_QUOTE_
#include"Quote.h"
#include<string>
class Disc_quote :public Quote
{
public:
Disc_quote() = default;
Disc_quote(const std::string& book, double price,std::size_t qty,double disc)
:Quote(book,price),quantity(qty),discount(disc) {}
double net_price(std::size_t)const = 0;
protected:
std::size_t quantity;
double discount = 0.0;
};
#endif // !DISC_QUOTE_
Bulk_quote.h
#ifndef BULK_QUOTE_H_
#define BULK_QUOTE_H_
#include"Disc_quote.h"
#include <string>
#include <iostream>
class Bulk_quote : public Disc_quote
{
public:
Bulk_quote() = default;
Bulk_quote(const std::string& book, double p, std::size_t qty, double disc) :Disc_quote(book,p,qty,disc) { }
double net_price(std::size_t) const override;
void debug() const override;
private:
std::size_t min_qty = 0;
double discount = 0.0;
};
double Bulk_quote::net_price(size_t cnt) const
{
if (cnt >= min_qty) return cnt * (1 - discount) * price;
else return cnt * price;
}
void Bulk_quote::debug() const
{
Quote::debug();
std::cout << "; min_qty: " << min_qty
<< "; discount: " << discount;
}
#endif
15.16
Limit_quote.h
#ifndef BULK_QUOTE_H_
#define BULK_QUOTE_H_
#include"Disc_quote.h"
#include <string>
#include <iostream>
class Limit_quote : public Disc_quote
{
public:
Limit_quote() = default;
Limit_quote(const std::string& book, double p, std::size_t qty, double disc) :Disc_quote(book, p, qty, disc) { }
double net_price(std::size_t) const override;
void debug() const override;
};
double Limit_quote::net_price(size_t cnt) const
{
if (cnt >quantity) return quantity * (1 - discount) * price+(cnt-quantity)*price;
else return cnt * price;
}
void Limit_quote::debug() const
{
Quote::debug();
std::cout << "; quantity: " << quantity
<< "; discount: " << discount;
}
#endif
15.17
#include"Quote.h"
#include"Bulk_Quote.h"
#include <iostream>
#include <functional>
double print_total(std::ostream& os, const Quote& item, size_t n)
{
double ret = item.net_price(n);
os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret << std::endl;
return ret;
}
int main()
{
Quote q("A1-001", 80);
Bulk_quote bq("A1-001", 80, 5, 0.2);
// print_total(std::cout, q, 10);
// print_total(std::cout, bq, 10);
q.debug();
std::cout << std::endl;
bq.debug();
std::cout << std::endl;
Disc_quote dq;
return 0;
}
15.20
class Base
{
public:
void memfcn(Base& b) { b = *this; };
protected:
int prot_mem;
private:
char priv_mem;
};
struct Pub_Derv : public Base
{
public:
void memfcn(Base& b) { b = *this; };
};
struct Priv_Derv : private Base
{
public:
void memfcn(Base& b) { b = *this; };
};
struct Prot_Derv : protected Base
{
public:
void memfcn(Base& b) { b = *this; };
};
struct Derived_from_Public : public Pub_Derv
{
public:
void memfcn(Base& b) { b = *this; };
};
struct Derived_from_Private : public Priv_Derv
{
public:
// void memfcn(Base &b) { b = *this; };
};
struct Derived_from_Protected : public Prot_Derv
{
public:
void memfcn(Base& b) { b = *this; };
};
int main()
{
Pub_Derv d1;
Priv_Derv d2;
Prot_Derv d3;
Derived_from_Public dd1;
Derived_from_Private dd2;
Derived_from_Protected dd3;
Base* p = &d1;
// p = &d2;
// p = &d3;
p = &dd1;
// p = &dd2;
// p = &dd3;
return 0;
}
15.22
#include<iostream>
#include<string>
class Shape
{
public:
typedef std::pair<double, double> Coordinate;
Shape() = default;
Shape(const std::string &n) :name(n) { }
virtual double area()const = 0;
virtual double perimeter() const = 0;
virtual~Shape() = default;
private:
std::string name;
};
class Rectangle :public Shape
{
public:
Rectangle() = default;
Rectangle(const std::string& n,
const Coordinate& a,
const Coordinate& b,
const Coordinate& c,
const Coordinate& d) :
Shape(n),a(a),b(b),c(c),d(d) {}
~Rectangle() = default;
protected:
Coordinate a;
Coordinate b;
Coordinate c;
Coordinate d;
};
class Square :public Rectangle
{
public:
Square() = default;
Square(const std::string& n,
const Coordinate& a,
const Coordinate& b,
const Coordinate& c,
const Coordinate& d) :
Rectangle(n,a,b,c,d) {}
~Square() = default;
};
int main()
{
return 0;
}
15.26
Quote.h
#ifndef QUOTE_H_
#define QUOTE_H_
#include <string>
#include <iostream>
class Quote
{
friend bool operator!=(const Quote& lhs, const Quote& rhs)
{
return lhs.bookNo != rhs.bookNo && lhs.price != rhs.price;
}
public:
Quote() = default;
Quote(const std::string& book, double sales_price) : bookNo(book), price(sales_price) {}
std::string isbn() const { return bookNo; }
Quote(const Quote&);
Quote(Quote&&)noexcept;
Quote& operator=(const Quote&);
Quote& operator=(Quote&&)noexcept;
virtual double net_price(std::size_t n) const { return n * price; }
virtual void debug() const;
virtual ~Quote() = default;
private:
std::string bookNo;
protected:
double price = 0;
};
void Quote::debug() const
{
std::cout << "bookNo: " << bookNo
<< "; price: " << price;
}
#endif
Bulk_quote.h
#ifndef BULK_QUOTE_H_
#define BULK_QUOTE_H_
#include"Disc_quote.h"
#include <string>
#include <iostream>
class Bulk_quote : public Disc_quote
{
public:
Bulk_quote() = default;
Bulk_quote(const std::string& book, double p, std::size_t qty, double disc) :Disc_quote(book,p,qty,disc) { }
Bulk_quote(Bulk_quote&);
Bulk_quote(Bulk_quote&&)noexcept;
Bulk_quote& operator=(Bulk_quote&);
Bulk_quote& operator=(Bulk_quote&&)noexcept;
double net_price(std::size_t) const override;
void debug() const override;
~Bulk_quote()override;
private:
std::size_t min_qty = 0;
double discount = 0.0;
};
double Bulk_quote::net_price(size_t cnt) const
{
if (cnt >= min_qty) return cnt * (1 - discount) * price;
else return cnt * price;
}
void Bulk_quote::debug() const
{
Quote::debug();
std::cout << "; min_qty: " << min_qty
<< "; discount: " << discount;
}
#endif
15.27
Bulk_quote.h
#ifndef BULK_QUOTE_H_
#define BULK_QUOTE_H_
#include"Disc_quote.h"
#include <string>
#include <iostream>
class Bulk_quote : public Disc_quote
{
public:
Bulk_quote() = default;
using Disc_quote::Disc_quote;
Bulk_quote(const std::string& book, double p, std::size_t qty, double disc) :Disc_quote(book,p,qty,disc) { }
Bulk_quote(Bulk_quote&);
Bulk_quote(Bulk_quote&&)noexcept;
Bulk_quote& operator=(Bulk_quote&);
Bulk_quote& operator=(Bulk_quote&&)noexcept;
double net_price(std::size_t) const override;
void debug() const override;
~Bulk_quote()override;
private:
std::size_t min_qty = 0;
double discount = 0.0;
};
double Bulk_quote::net_price(size_t cnt) const
{
if (cnt >= min_qty) return cnt * (1 - discount) * price;
else return cnt * price;
}
void Bulk_quote::debug() const
{
Quote::debug();
std::cout << "; min_qty: " << min_qty
<< "; discount: " << discount;
}
#endif
15.28
#include "Quote.h"
#include "Bulk_quote.h"
#include "Limit_quote.h"
#include <iostream>
#include <functional>
#include <vector>
#include <memory>
double print_total(std::ostream &os, const Quote &item, size_t n)
{
double ret = item.net_price(n);
os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret << std::endl;
return ret;
}
int main()
{
Quote q("A1-001", 80);
Bulk_quote bq("A1-001", 80, 5, 0.2);
Limit_quote lq("A1-001", 80, 5, 0.2);
print_total(std::cout, q, 10);
print_total(std::cout, bq, 10);
print_total(std::cout, lq, 10);
double total_price = 0;
std::vector<Quote> vector_quote;
vector_quote.push_back(bq);
for(const auto &q : vector_quote)
total_price += q.net_price(10);
std::cout << "total_price:" << total_price << std::endl;
return 0;
}
15.29
当派生类对象被赋值给基类对象时,其中的派生类部分将被“切掉”,因此容器和存在继承关系的类型无法兼容。
而使用指针时,调用的是net_price版本依赖于指针所指对象的动态类型
#include "Quote.h"
#include "Bulk_quote.h"
#include "Limit_quote.h"
#include <iostream>
#include <functional>
#include <vector>
#include <memory>
double print_total(std::ostream &os, const Quote &item, size_t n)
{
double ret = item.net_price(n);
os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret << std::endl;
return ret;
}
int main()
{
Quote q("A1-001", 80);
Bulk_quote bq("A1-001", 80, 5, 0.2);
Limit_quote lq("A1-001", 80, 5, 0.2);
print_total(std::cout, q, 10);
print_total(std::cout, bq, 10);
print_total(std::cout, lq, 10);
std::vector<std::shared_ptr<Quote>> basket;
// basket.push_back(std::make_shared<Quote>(q));
basket.push_back(std::make_shared<Bulk_quote>(bq));
// basket.push_back(std::make_shared<Limit_quote>(lq));
double total_price = 0;
for (const auto &vq : basket)
total_price += vq->net_price(10);
std::cout << "total_price:" << total_price << std::endl;
return 0;
}
15.30
Basket.h
#ifndef BASKET_H_
#define BASKET_H_
#include "Quote.h"
#include <iostream>
#include <memory>
#include <set>
class Basket
{
public:
void add_item(const std::shared_ptr<Quote> &sale) { items.insert(sale); }
void add_item(const Quote &sale) { items.insert(std::shared_ptr<Quote>(sale.clone())); }
void add_item(Quote &&sale) { items.insert(std::shared_ptr<Quote>(std::move(sale).clone())); }
double total_receipt(std::ostream&) const;
private:
static bool compare(const std::shared_ptr<Quote> &lhs, const std::shared_ptr<Quote> &rhs) { return lhs->isbn() < rhs->isbn(); }
std::multiset<std::shared_ptr<Quote>, decltype(compare) *> items{compare};
};
#endif
Basket.cpp
#include "Basket.h"
double Basket::total_receipt(std::ostream &os) const
{
double sum = 0.0;
for(auto iter = items.cbegin(); iter != items.cend(); iter = items.upper_bound(*iter))
{
sum += print_total(os, **iter, items.count(*iter));
}
os << "Total Sale: " << sum << std::endl;
return sum;
}
main.cpp
#include "Quote.h"
#include "Bulk_quote.h"
#include "Limit_quote.h"
#include "Basket.h"
#include <iostream>
#include <functional>
#include <vector>
#include <memory>
int main()
{
Bulk_quote bq("A1-001", 80, 5, 0.2);
print_total(std::cout, bq, 10);
std::vector<std::shared_ptr<Quote>> basket;
basket.push_back(std::make_shared<Bulk_quote>(bq));
// double total_price = 0;
// for (const auto &vq : basket)
// total_price += vq->net_price(10);
// std::cout << "total_price:" << total_price << std::endl;
Basket basket_object;
for (int i = 0; i < 10; ++i)
{
basket_object.add_item(bq);
}
basket_object.total_receipt(std::cout);
return 0;
}
15.35
Query.h
#ifndef QUERY_H_
#define QUERY_H_
#include <string>
#include <iostream>
#include "Query_base.h"
#include "WordQuery.h"
#include "TextQuery.h"
class Query
{
friend Query operator~(const Query&);
friend Query operator|(const Query&, const Query&);
friend Query operator&(const Query&, const Query&);
public:
Query(const std::string&);
QueryResult eval(const TextQuery &t) const { return q->eval(t); }
std::string rep() const { return q->rep(); }
private:
Query(std::shared_ptr<Query_base> query) : q(query) { }
std::shared_ptr<Query_base> q;
};
std::ostream& operator<<(std::ostream &os, const Query &query)
{
return os << query.rep();
}
inline Query::Query(const std::string &s) : q(new WordQuery(s)) { std::cout << "Query::Query(const std::string &s)" << std::endl; }
#endif
Query_base.h
#ifndef QUERY_BASE_H_
#define QUERY_BASE_H_
#include <string>
#include <iostream>
#include "TextQuery.h"
#include "Query.h"
class Query_base
{
friend class Query;
protected:
using line_no = TextQuery::line_no;
virtual ~Query_base() = default;
private:
virtual QueryResult eval(const TextQuery&) const = 0;
virtual std::string rep() const = 0;
};
#endif