#pragma once
#include <string>
#include <ostream>
#include <iostream>
class Disc_Quote;//Disc_Quote即将被使用,它将是Quote的派生。若只声明,无需写出它的 派生访问列表
class Quote//类在被用作基类之前,必须已经定义,而不仅仅是声明,派生类需要知道基类有什么样的成员
{
public:
Quote()
{
std::cout << "call Quote DefaultConstructor" << std::endl;
}
Quote(const std::string &book, double sales_price) :bookno(book), price(sales_price)
{
std::cout << "call Quote Constructor" << std::endl;
}
Quote(const Quote & rhs)
{
bookno = rhs.bookno;
price = rhs.price;
std::cout << "call Quote copyConstructor" << std::endl;
}
Quote& operator =(const Quote& rhs)
{
bookno = rhs.bookno;
price = rhs.price;
std::cout << "call Quote operator = " << std::endl;
return *this;
}
std::string isbn()const
{
return bookno;
}
virtual double net_price(std::size_t n)const
{
return n*price;
}
virtual void debug()
{
std::cout << "bookno :" << bookno << " price" << price << std::endl;
}
virtual ~Quote()
{
std::cout << "call Quote destructor" << std::endl;
}
private:
std::string bookno;
protected://只有派生类能访问
double price = 0.0;
};
class Disc_Quote :public Quote
{
public:
Disc_Quote()
{
std::cout << "call DiscQuote DefaultConstructor" << std::endl;
}
Disc_Quote(const std::string &book, double price, std::size_t qty, double disc) :Quote(book, price),
quantity(qty), discount(disc)//每个类控制自己成员的初始化部分,同时每个派生类只需要负责自己的直接基类的初始化
{
std::cout << "call DiscQuote Constructor" << std::endl;
}
//如果不调用基类的拷贝构造函数,则会使用基类的默认构造函数来初始化派生类中的基类部分
//同时rhs虽然静态类型是Disc_Quote,但是Quote的拷贝构造函数的参数是Quote引用,
//因此这里存在一个派生类向基类的隐式转换。
//我在看《c++prime》第15章之前,一直以为只有派生类的指针可以向基类指针转换。
//但实际
Disc_Quote(const Disc_Quote&rhs) :Quote(rhs)
{
quantity = rhs.quantity;
discount = rhs.discount;
std::cout << "call Disc_Quote CopyConstructor" << std::endl;
}
Disc_Quote& operator = (const Disc_Quote&rhs)
{
//调用基类赋值操作符,无论它是合成的操作还是自定义操作,因为需要处理派生类中的基类部分
Quote::operator =(rhs);
quantity = rhs.quantity;
discount = rhs.discount;
std::cout << "call Disc_Quote operator = " << std::endl;
return *this;
}
double net_price(std::size_t n) const = 0 ;
~Disc_Quote()
{
std::cout << "call Disc_Quote destructor" << std::endl;
}
void debug()override
{
Quote::debug();
std::cout << "quantity:" << quantity << " dicount" << discount << std::endl;
}
protected:
std::size_t quantity = 0;
double discount = 0.0;
};
class Buck_Quote :public Disc_Quote
{
public:
Buck_Quote()
{
std::cout << "call Buck_Quote Constructor" << std::endl;
}
~Buck_Quote()
{
std::cout << "call Buck_Quote destructor" << std::endl;
}
Buck_Quote(const Buck_Quote&rhs):Disc_Quote(rhs)//在构造函数列表调用基类构造函数
{
std::cout << "call Buck_Quote CopyConstructor" << std::endl;
}
Buck_Quote& operator=(const Buck_Quote&rhs)
{
Disc_Quote::operator=(rhs);
std::cout << "call Buck_Quote operator =" << std::endl;
return *this;
}
Buck_Quote(const std::string &, double, std::size_t, double);
double net_price(std::size_t n) const override;//重写基类成员
private:
};
double print_total(std::ostream &os, const Quote&item, size_t n);
。。。。。
#include "Quote.h"
Buck_Quote::Buck_Quote(const std::string &book, double p, std::size_t qyy, double disc)
:Disc_Quote(book, p, qyy, disc)
{
std::cout << "call Buck_Quote construct" << std::endl;
}
double Buck_Quote::net_price(std::size_t cnt)const
{
if (cnt>=quantity)
{
return cnt*(1 - discount)*price;
}
else
{
return cnt *price;
}
}
double print_total(std::ostream &os, const Quote&item, size_t n)
{
double ret = item.net_price(n);
os << "isbn" << item.isbn() << " total due " << ret << std::endl;
return ret;
}
。。。
#include "Quote.h"
#include <iostream>
int main()
{
Buck_Quote b1("b1", 3, 4, 0.2);
b1.debug();
std::cout << "***" << std::endl;
Quote q1("q1", 3);
q1.debug();
std::cout << "***" << std::endl;
Buck_Quote b2(b1);
b2.debug();
std::cout << "***" << std::endl;
Buck_Quote b3("b3", 5, 7, 0.9);
b3.debug();
std::cout << "***" << std::endl;
b2 = b3;
b2.debug();
/*print_total(std::cout, b1, 5);
print_total(std::cout, q1, 5);*/
system("pause");
return 0;
}