c++ primer 第十五章习题

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;
}

猜你喜欢

转载自blog.csdn.net/qq_25037903/article/details/82940587