15-1 OOP概述
核心思想
面向对象程序设计(object-oriented programming)的核心思想是
- 封装:类的接口和实现分离
- 继承:定义相似的类型并对相似关系建模
- 动态绑定:在一定程度上忽略类的区别,而以统一的方式使用它们
继承
在C++中,将类型相关的函数与派生类不做改变直接继承 的函数区分对待。
对于类型相关的函数要声明为虚函数
//定义基类
class Quote{
public :
string isbn() const;
virtual double net_price(int n) const;
};
//定义派生类
class Bulk_Quote : public Quote{
public :
double net_price(int i) const override;
};
-
派生列表:派生类通过派生列表指出它的父类,每个父类前都有访问说明符
public指出我们完全可以把Bulk_Quote当作Quote使用
-
基类通过
virtual
声明虚函数;派生类必须声明虚函数。可在派生类的虚函数后加上override
显式表明它是重载的虚函数
动态绑定
通过使用动态绑定(dynamic binding),我们能用同一段代码分别处理Quote 和Bulk _quote的对象。
double print_total(ostream &os, const Quote &item,
int n){
//根据传入的参数的对象类型调用Quote::net_price
//或者Bulk_Quote::net_price
double ret = item.net_price(n);
os<<"ISBN: "<< item.isbn()
<<" # sold: "<<n<<" total due: "<<ret<<endl;
return ret;
}
由于传入的是基类对象,所以既可以传入基类对象,也可以传入派生类对象。
对象的类型决定了net_price的执行
//basic是Quote类型,bulk是Bulk_Quote类型
print_total(cout, basic, 20); //执行Quote的net_price
print_total(cout, bulk, 20); //执行Bulk_Quote的net_price
因为在上述过程在运行时选择函数的版本,所以动态绑定有时又被称为运行时绑定(run-time binding)。
何时发生动态绑定?
使用基类的引用(或指针)调用一个虚函数时