什么是C++面向对象编程

目前最常用的编程方法有两种,即:过程式编程面向对象编程(Object-Oriented Programming, OOP)

过程式编程是一种以执行程序操作的过程或函数为中心编写软件的方法。程序的数据通常存储在变量中,与这些过程是分开的。所以必须将变量传递给需要使用它们的函数。与之不同的是,面向对象编程则是以对象为中心。

过程式编程对于软件开发人员来说已经有好多年了。然而,随着程序变得越来越复杂,程序数据与运行代码的分离可能会导致问题。例如,程序的规范经常会发生变化,从而需要更改数据的格式或数据结构的设计。当数据结构发生变化时,对数据进行操作的代码也必须更改为接受新的格式。查找需要更改的所有代码会为程序员带来额外的工作,并增加了使代码出现错误的机会。

这个问题促成了从过程式编程向面向对象编程的转变。OOP 以创建和使用对象为中心。一个对象(Object)就是一个软件实体,它将数据和程序在一个单元中组合起来。对象的数据项,也称为其属性,存储在成员变量中。对象执行的过程被称为其成员函数。将对象的数据和过程绑定在一起则被称为封装

注意,在有些面向对象的编程语言中,对象执行的过程称为方法。

图 1 显示了一个Circle对象的外观。它只有一个保存数据的成员变量和两个成员函数。Circle对象的成员变量是radius。其setRadius成员函数用于设置radius半径,而calcArea 成员函数则用于计算并返回圆面积。

Circle对象包含一个成员变量和两个成员函数
图 1 Circle 对象包含一个成员变量和两个成员函数

成员变量和成员函数都是 Circle 对象的成员,它们被绑定在同一个单元中。当需要执行操作(例如计算圆的面积)时,即可将消息传递给对象,告诉它执行 caclArea 函数。因为 caclArea 是 Circle 对象的成员,它可以自动访问对象的成员变量,因此,无须将 radius 半径值传递给 caclArea 函数。

除了将相关联的数据和函数绑定在一起,对象还允许数据隐藏。数据隐藏是指对象将其数据隐藏起来,让对象之外的代码无法访问的能力。只有对象的成员函数才可以直接访问并更改其数据。对象通常会隐藏其数据,但允许外部代码通过其某些成员函数访问它。

如图 2 所示,Circle 对象的成员函数给对象外部的编程语句提供了一种可以间接访问对象数据的方法。

对象的成员函数允许外部代码间接访问对象的数据
图 2 对象的成员函数允许外部代码间接访问对象的数据

为什么隐藏信息是一件好事呢?当对象的内部数据被隐藏,外部代码无法访问时,只有通过对象的成员函数才能访问数据,这样可以保护数据免受意外或有意的损坏。另外,对象之外的编程代码不需要知道对象数据的格式或内部结构,代码只需要与对象的函数进行交互。

当程序员改变对象内部数据的结构时,对象的成员函数也会被修改,以便它们仍然可以正常运行。但是,这些更改与对象外的代码无关,它们无须进行任何更改。调用和使用对象成员函数的方法与修改之前完全相同。

例如,我们使用汽车作为抽象对象的一个示例,谈到人们可以使用它,而不必了解它的具体工作原理。不仅如此,汽车有一个相当简单的接口,包括一个点火开关、方向盘、加油踏板、制动踏板和一个挡位选择器(带手动变速器的车辆也提供离合器踏板)。如果有人想要驾驶汽车,那么他只需要学习操作这些接口元素即可,比如说:
  • 要发动引擎,只需转动点火开关中的钥匙,汽车内部发生的事情与司机无关。
  • 如果要让汽车左转,则只需转动方向盘,连接方向盘和前轮胎的所有连接部件都会发生运动让汽车左转,至于其中原理司机并不需要知晓。
  • 如果制造商重新设计车辆,以不同的方式执行某一项后台操作,司机也不需要学习新的接口。

因为汽车有简单的用户接口,所以它们可以由没有机械知识的人来驾驶。这对汽车制造商是有好处的,因为这意味着有更多的人可能成为客户。它对汽车的用户也是有好处的,因为他们只要学习几个简单的操作步骤,就几乎可以驾驶任何车辆。

这同样也是软件开发中让人关切的问题。一个程序很少是只由一个人编写完成的,例如,如果加入了 C++ 库函数,或者像 cin 和 cout 那样的对象,则使用了别人写的代码。在专业软件开发的世界中,程序员通常在团队中工作,他们可能购买他人的代码,也可以销售自己的代码,并在项目上进行协作。使用 OOP,程序员可以创建具有强大引擎的对象,而在底层模式的简单接口又可以保护对象的算法和数据。