从C语言到C++语言,是面向过程到面向对象编程的跨越。面向对象编程的特点就是继承和动态绑定。C++通过类的派生来实现继承,通过虚拟函数支持动态绑定,虚拟函数提供了一些封装类体系实现细节的方法。
面向对象编程的关键概念
抽象(abstraction)——去除对象中不必要的细节,保留描述对象本质特征的关键字,抽象是一种设计活动。
类 —— 是一种用户自定义类型,就好像int这样的内置类型一样。类机制必须允许程序员规定它所定义的类能够进行的操作。类里面的东西任何东西被称为类的成员。概括 说, 类是由一组数据结构和定义在该结构上的一组操作的集合。
对象(object)——某个类的一个特定变量,对象也被称作类的实例
封装(encapsulation)——把类型、数据和函数组合在一起组成一个类。
继承(inheritance)——允许类从一个更简单的基类中接受数据结构和函数。派生类可获得基类的数据和操作,并可根据需要对它们进行改写,也可以在派生类中增加新的数据类型和函数。
—————————————————————————————————————————————————————————————————————————————
抽象
抽象——就是观察一群事物,并认识到它们具有一些共同的主题,只记录能表现事物特征的关键数据项。当你这样做的时候就是在进行抽象,所存储的数据类型就是抽象数据类型。抽象本身是对事物的简化。
抽象建立了一种抽象数据类型,C++使用类(class)这个特性来实现它。它提供了一种自上向下的、观察数据类型属性的方法来看待封装:把用户定义类新型中的各种数据结构和方法组合在一起。它同时也提供一种从底向上的观点看封装:把各种数据和方法组合在一起实现一种永和自定义类型。
抽象的好处:
- 隐藏不相关的细节,把注意力集中在本质的特征上。
- 向外部提供一个黑盒子接口。接口确定了施加在对象之上的 有效操作的集合,但不对外提供内部的实现细节。
- 把一个复杂的系统分解成几个相互独立的模块。这样可以做到分工明确,避免组件中间不符合规则的相互作用。
- 重用和共享代码。
—————————————————————————————————————————————————————————————————————————————
封装
当你把抽象数据类型和他们的操作捆绑在一起的时候,就是进行封装。非OOP语言没有完备的机制来实现封装。
程序设计艺术的当前状态就是面向对象语言,它们通过把用户自定义的数据结构和用户定义的能够在这些数据结构上进行操作的函数捆绑在一起实现了数据的完整性,别的函数无法访问这些内部数据。
—————————————————————————————————————————————————————————————————————————————
访问控制
访问控制说明了谁可以访问接下来声明的数据或函数。C++中访问控制如下
- public 属于public的声明在类的外部可见,并可按需进行设置、调用和操纵。一般的原则是不要把类的数据做成public,因为让类的数据保持私有才符合面向对象的理论之一;只有类本身才可以改变自己的数据,外部函数只能调用类的成员函数,这就保证了类的数据只会以合乎规则的方式被更新。
- protected 声明的内容只能由该类本身的函数以及从该类所派生的类的函数使用。
- private 属于private的声明只能被该类的成员函数使用,private声明时类外部可见的,但确实不能访问的
- friend 属于friend的函数不属于类的成员函数,但它可以像类的成员函数一样访问类的private和protected成员。friend可以是一个函数也可以是一个类.
(后两者每次只能用于一条声明)
————————————————————————————————————————————————————————————————————————————
声明
C++类的声明就是正常的额C声明,内容包括函数、类型或数据。类把他们捆绑在一起,类中的每个函数都需要一个实现,通常的做法是将它们放在类外部。
class Fruit{
public:
peel();
slice();
juice();
private:
int weight;
int height;
};
当成员函数在类外部实现时,前面必须加一些特别的前缀::。“::”被称作“全局范围分解符”,跟在他前面的就是进行查找的范围。如果::前面没有标示符就表示查找范围为全局范围。
void Fruit::peel(){ std::cout<<"in peel"<<endl;}
调用成员函数
Fruit melon, orange, banana;
main(){
melon.slice();
orange.juice();
return 0;
}
调用一个类的对象的成员函数相当于面向对象编程语言使用的“向对象发送一条信息”术语。
每个成员函数都有一个this指针,它是隐式赋给函数的,它允许对象在成员函数内部引用对象本身。
—————————————————————————————————————————————————————————————————————————————
构造函数和析构函数
当类的一个对象被创建时,构造函数就会被隐式调用,它负责对象的初始化。与之相对应的,类存在一个清理函数称为析构函数。当对象被销毁(超出生存范围或进行delelte操作,回收它所使用的堆内存),析构函数就自动调用。析构函数不如构造函数常用,它里面的代码一般用于处理一些特殊的终止要求以及垃圾回收等。析构函数不仅能清除对象,还清理对象所持有的锁。
构造函数和析构函数是非常需要的,因为类外部的任何函数都不能访问类的private数据成员,因此需要类内部有个特权函数来创建一个对象并对其初始化。