C++ Primer 第五版(中文版) ----容器与继承练习15.28 & 15.29

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

disc_quote.h

#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


bulb_quote.h

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

}

Running result:

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
请按任意键继续. . .


你可能感兴趣的:(C++ Primer 第五版(中文版) ----容器与继承练习15.28 & 15.29)