面向对象程序设计基于三个基本概念:数据抽象、继承和动态绑定。
继承和动态绑定对程序的编写有两方面的影响:一是我们可以更容易的定义与其他类相似但不完全相同的新类:二是在使用这些彼此相似的类编写程序时,我们可以在一定程度上忽略掉它们的区别。
继承
通过继承联系在一起的类构成一种层次关系。通常在层次关系的根部有一个基类,其他类型则直接或间接的从基类继承而来,这些继承得到的类称为派生类。
在C++语言中,基类将类型相关的函数与派生类不做改变直接继承的函数区分对待。对于某些函数,基类希望它的派生类各自定义适合自身的版本,此时 基类将这些函数声明成虚函数。
派生类必须通过使用类派生列表明确指出它是从哪个基类继承而来。
动态绑定
在C++语言中,当我们使用基类的引用(或指针)调用一个虚函数时将发生动态绑定。
定义派生类
派生类可以在他覆盖的函数前使用virtual关键字。C++11新标准中允许派生类显示的注明他使用某个成员函数覆盖了它的继承的虚函数。具体做法是在形参列表后面、或者在const成员函数的const关键字后面、或者在引用成员函数的引用限定符后面添加一个关键字override。
派生类使用基类的成员
派生类可以访问基类的公有成员和受保护成员。
防止继承的发生
练习15.7:
定义一个类使其实现一种数量受限的折扣策略,具体策略是:当购买书籍的数量不超过一个给定的限量时享受折扣,如果购买量一旦超过了限量,则超出的部分将以原价销售。
#include
<iostream>
#include
<string>
using
namespace
std;
class
Quote
{
public
:
Quote() =
default
;
Quote(
const
string
&
b
,
double
p
) :bookNo(
b
), price(
p
){}
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;
};
class
Bulk_Quote
:
public
Quote
{
public
:
Bulk_Quote() =
default
;
Bulk_Quote(
const
string
&
b
,
double
p
,
size_t
q
,
double
disc
) :
Quote
(
b
,
p
), min_qty(
q
), discount(
disc
){ }
double
net_price(
size_t
n)
const
override
;
private
:
size_t
min_qty = 0;
double
discount = 0.0;
};
double
Bulk_Quote
::net_price(
size_t
n
)
const
{
return
n
*price*(
n
>= min_qty ? 1 - discount : 1);
}
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;
}
int
main()
{
Quote
q(
"textbook"
, 10.60);
Bulk_Quote
bq(
"textbook"
, 10.60, 10, 0.3);
print_total(cout, q, 12);
print_total(cout, bq, 12);
return
0;
}