C++Primer第五版(中国語版)----容器と継承練習15.28&15.29

10255 ワード

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.
"; } Quote(const std::string &b, const double p) : bookNo(b), price(p){std::cout << "Quote:constructor taking 2 parameters
";} //copy constructor Quote(const Quote &q) :bookNo(q.bookNo), price(q.price){ std::cout << "Quote:copy constructor!
"; } //move constructor Quote(Quote &q) :bookNo(std::move(q.bookNo)), price(std::move(q.price)) {std::cout << "Quote : move constructor!
";} //copy = Quote & operator=(const Quote & rhs) { if (*this != rhs) { bookNo = rhs.bookNo; price = rhs.price; } std::cout << "Quote:copy = ()
"; 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 = !!!!!!!!!!!
"; 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:
" << "bookNo = " << bookNo << " " << "price = " << price << "
"; } virtual ~Quote() { std::cout << "destructing Quote
"; } 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
"; } 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.
";} //copy Disc_quote(const Disc_quote & dq) :Quote(dq), quantity(dq.quantity), discount(dq.discount) {std::cout << "Disc_quote: copy constructor.
";} //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.
";} //! copy =() Disc_quote& operator =(const Disc_quote& rhs) { Quote::operator =(rhs); this->quantity = rhs.quantity; this->discount = rhs.discount; std::cout << "Disc_quote : copy =()
"; 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 =()
"; return *this; }*/ virtual double net_price(std::size_t n) const override = 0; ~Disc_quote() { std::cout << "destructing Dis_quote
"; } 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
"; } 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.
"; } //! 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
"; } */ using Disc_quote::Disc_quote; //! copy constructor Bulk_quote(const Bulk_quote& bq) : Disc_quote(bq) { std::cout << "Bulk_quote : copy constructor
"; } //! move constructor Bulk_quote(Bulk_quote&& bq) : Disc_quote(std::move(bq)) { std::cout << "Bulk_quote : move constructor
"; } //! copy =() Bulk_quote& operator =(const Bulk_quote& rhs) { Disc_quote::operator =(rhs); std::cout << "Bulk_quote : copy =()
"; return *this; } //! move =() Bulk_quote& operator =(Bulk_quote&& rhs) { Disc_quote::operator =(std::move(rhs)); std::cout << "Bulk_quote : move =()
"; return *this; } double net_price(std::size_t n) const override; void debug() const override; ~Bulk_quote() override { std::cout << "destructing Bulk_quote
"; } }; 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:
" << "min_qty= " << quantity << " " << "discount= " << this->discount << "
"; } #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:
" << "max_qty= " << this->quantity << " " << "discount= " << this->discount << "
"; } }; #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 << "======================

"; double total = 0; for (const auto& b : v) { total += b.net_price(20); } std::cout << total << std::endl; std::cout << "======================

"; /** * @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 << "======================

"; 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
       . . .