面向对象
面向对象程序设计(Object-oriented programming,OOP)是种具有对象概念的程序编程典范,同时也是一种程序开发的抽象方针。
面向对象三大特征 —— 封装、继承、多态
封装
把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。关键字:public, protected, private。不写默认为 private。
public
成员:可以被任意实体访问protected
成员:只允许被子类及本类的成员函数访问private
成员:只允许被本类的成员函数、友元类或友元函数访问
继承
- 基类(父类)——> 派生类(子类)
继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。
多态
- 多态,即多种状态(形态)。简单来说,我们可以将多态定义为消息以多种形式显示的能力。
- 多态是以封装和继承为基础的。
- C++ 多态分类及实现:
- 重载多态(Ad-hoc Polymorphism,编译期):函数重载、运算符重载
- 子类型多态(Subtype Polymorphism,运行期):虚函数
- 参数多态性(Parametric Polymorphism,编译期):类模板、函数模板
- 强制多态(Coercion Polymorphism,编译期/运行期):基本类型转换、自定义类型转换
静态多态(编译期/早绑定)
函数重载
class A
{
public:
void do(int a);
void do(int a, int b);
};
动态多态(运行期期/晚绑定)
- 虚函数:用 virtual 修饰成员函数,使其成为虚函数
- 动态绑定:当使用基类的引用或指针调用一个虚函数时将发生动态绑定
注意:
- 可以将派生类的对象赋值给基类的指针或引用,反之不可
- 普通函数(非类成员函数)不能是虚函数
- 静态函数(static)不能是虚函数
- 构造函数不能是虚函数(因为在调用构造函数时,虚表指针并没有在对象的内存空间中,必须要构造函数调用完成后才会形成虚表指针)
- 内联函数不能是表现多态性时的虚函数,解释见:虚函数(virtual)可以是内联函数(inline)吗?
动态多态使用
class Shape // 形状类
{
public:
virtual double calcArea()
{
...
}
virtual ~Shape();
};
class Circle : public Shape // 圆形类
{
public:
virtual double calcArea();
...
};
class Rect : public Shape // 矩形类
{
public:
virtual double calcArea();
...
};
int main()
{
Shape * shape1 = new Circle(4.0);
Shape * shape2 = new Rect(5.0, 6.0);
shape1->calcArea(); // 调用圆形类里面的方法
shape2->calcArea(); // 调用矩形类里面的方法
delete shape1;
shape1 = nullptr;
delete shape2;
shape2 = nullptr;
return 0;
}