C++语言被称为 C with Classes、A Better C 或者“C 的超级”,通过简单的处理,C++确实可以编译 C 语言的几乎所有代码。所以可以简单地这么说:“C包含于 C++,是 C++的一个子集。”C++对 C的扩充可不是简单的“++”那么简单。C++对 C的扩充主要表现在面向对象和泛型编程两个部分。当然除了这两部分的重大功能外,C++对C语言的基础方面如函数、变量类型等也进行了完善和添加。
(1)写过C++程序的程序员应该都见过bool(布尔)类型和引用类型。bool 变量是C++固有的内置变量类型,一般占有1 字节。bool变量取值只有false和true。C 语言在 C99 标准之前没有 bool 变量。如果 C 程序员想使用 bool类型,需自己定义。例如:
typedef enum {false = 0, true - 1} bool;
引用是C++语言区别于C语言的一个新引入的重要扩充,它是被绑定变量或对象的别名,就像我们小时候的乳名和上学时的学名一样,无论别人叫你乳名还是学名指的都是你。假设定义一个变量如下:
int nNumber=5;
int &refNumber =nNumber;
nNumber是5对应4Bytes内存的标识名称(对应你的乳名),refNumber是nNumber的引用或别名(对应你的学名)。
(2)函数是C++和 C语言中同时存在的。C++中的函数具备C语言函数的一切使用方式,但是 C++对函数使用灵活性进行了最大的挖掘。C++中的函数支持函数的重载、内联,同时还支持函数的引用调用。这些都是C语言所不具有的功能。这些使用方式的添加,使得 C++语言更接近自然语言。
(3)C++是面向对象的编程语言,这是C++区别于C语言最根本的地方—C语言是面向过程语言。
从哲学的角度思考,一种设计语言要实现两个相关的目标:一方面,提供一种手语言即是基于此目标设计的,因此C语言是面向机器的程序设计语言,即通常所说的面向过程,面向过程技术以函数为基础,通过一系列的函数完成过程的实现;第二个目的要求语言是“接近问题的”,C++即基于此目标设计的,C++通过一系列的类实现面向问题的解决方案。
因此C++是面向问题的设计语言,即通常所说的面向对象。面向对象技术是一种以对象为基础,以事件或消息来驱动对象执行处理的程序设计技术。它具有抽象性、封装性、继承性及多态性。
注意:面向对象编程的关键思想是多态性。在C++中,通过基类的引用(或指针)调用虚函数时,发生动态绑定。这是C++中多态性的基础。C++的多态包括两种:一种是运行时的多态,另一种为编译时的多态。
面向过程和面向对象的区别
(1)面向过程程序设计方法采用函数(或过程)来描述对数据的操作,但又将函数与其操作的数据分离开来;面向对象程序设计方法将数据和对数据的操作封装在一起,作为一个整体来处理,函数与数据不分离。
(2)面向过程程序设计方法以功能为中心来设计功能模块,难以维护;而面向对象程序设计方法以数据为中心来描述系统,数据相对于功能而言具有较强的稳定性,因此更易于维护。
(3)面向过程程序的控制流程由程序中预定的顺序来决定;面向对象程序的控制流程由运行时各种事件的实际发生来触发,而不再由预定顺序来决定,更符合实际需要。
(4)面向对象程序设计方法可以利用框架产品(如 MFC,Microsoft Foundation Classes)进行编程。面向对象和面向过程的根本区别在于封装后,面向对象提供了面向过程不具备的各种特性,最主要的就是继承和多态。
(5)面向对象技术具有程序结构清晰、自动生成程序框架、实现简单、可有效减少程序的维护工作量、代码重用率高、软件开发效率高等优点。
(6)封装将对象有关的数据和行为封装成整体来处理,使得对象以外的部分不能随意存取对象的内部属性,从而有效地避免了外部错误对它的影响,大大减小了查错和排错的难度。另外,当修改对象内部时,由于只有少量的外部接口对外提供服务,因此同样减小了内部的修改对外部的影响。如果一味地强调封装,对象的任何属性都不允许外部直接存取,则要增加许多没有其他意义、只负责读或写的行为,这会为编程工作增加负担,增加运行开销,并且使程序显得臃肿。为了避免这一点,在程序的具体实现过程中应使对象有不同程度的可见性,进而与具体情况相符合。
(7)基于C++编程更加容易。因为面向对象更接近于现实,所以可以从现实出发,进行适当的抽象。在软件工程上,面向对象可以使工程更加模块化,实现更低的耦合和更高的内聚。在设计模式上(似乎只有面向对象才涉及设计模式),面向对象可以更好地实现开-闭原则,也使代码更易阅读。相对而言,面向过程程序设计是面向对象程序设计的基础,面向对象的程序里面一定会有面向过程的程序片段。
注意:C和C++的根本区别为,是否面向对象,但并不是说面向对象的C++代码中就一定不存在面向过程的思想。从最终实现功能上比较,两者没有任何区别。C++可以实现的功能,C语言也一定可以实现。面向对象的特点包括封装、多态和继承,其中多态又分为重载和重写。面向对象的编程思想更加接近现实的事物。
为什么要应用继承机制?客观事物既有共性,也有特性。如果只考虑事物的共性,而不考虑事物的特性,就不能反映出客观世界中事物之间的层次关系。抽象机制是考虑事物的共性,继承机制是考虑事物的特性,这样才能完整地描述客观世界的层次关系。继承能使软件模块具有可重用性、独立性,缩短软件开发周期,提高软件开发效率,同时使软件易于维护。
C++的多态性分为编译时多态和运行时多态两种。编译时多态是指在程序的编译阶段由编译系统根据参数确定与哪个同名的函数相联系;运行时多态是指在程序的运行阶段才根据产生的信息确定需要调用哪个同名的函数。C++通过函数重载和运算符重载实现编译时多态,通过继承和虚函数来实现运行时多态。面向对象的多态性指的是运行时多态,后续将要讲述的泛型编程即编译时多态。
泛型编程是C++中的一个概念,泛型编程所依赖的多态是上文中的编程时多态,主要就是通过模板机制来构建一类操作类似,但数据不同的程序,其中有函数模板和类模板。
泛型的第一个好处是编译时的严格类型检查。这是集合框架最重要的特点。此外,泛型消除了绝大多数的类型转换。如果没有泛型,在使用集合框架时,就不得不进行类型转换。关于泛型的理解可以总结为一句话:它把数据类型作为一种参数传递进来。
为了更好地说明泛型编程到底是怎么回事,来看一下堆栈类模板的代码实现:
//堆栈中元素的最大个数
const int MAX ELEM NUMBER =100;
// 堆栈类模板,主要实现数据栈的压栈和出栈功能
template <class T>
{
public:
CStack(void);
virtual~CStack(void);
TPop(void); //出栈操作
bool Push(T Elem); //压栈操作
private:
Tm tData[MAX ELEM NUMBER]; //堆栈空间
int m nDataPtr: //堆栈指针
};
template<classT>CStack<T>::CStack(void)
{
m_nDataPtr =-1;
memset(m_tData,0,MAX_ELEM_NUMBER*sizeof(T));
}
template<class T>CStack<T>::~CStack(void)
{
}
//实现堆栈的出栈操作
template<class T>T CStack<T>::Pop(void)
{
//出栈函数实现
return 0
//实现堆栈的压栈操作
template<class T>bool CStack<T>:Push(T Elem)
{
//压栈操作实现
return false:
}
模板实例化时T传入不同的类型,可生成不同的 CStack 类类型。如定义一个int类型的堆栈:
CStack<int> StackInt;
泛型 StackInt 实例类类型代码:
//整型数据栈类,主要实现整型数据栈的压栈和出栈功能
class CStack
{
public:
CStack(void);
virtual~CStack(void);
int Pop(void);
//出栈操作
bool Push(int Elem); //压栈操作
private:
Tm_tData[MAX_ELEM NUMBER]; //堆栈空间
int m nDataPtr; //堆栈指针
};
CStack::CStack(void)
{
m_nDataPtr=-1;
memset(m tData,0, MAX_ELEM_NUMBER*sizeof(int));
}
CStack::~CStack(void)
//实现整型堆栈的出栈操作
int CStack::Pop(void)
{
//整型数据出栈函数实现
return 0:
}
//实现整型堆栈的压栈操作
boo1 CStack::Push(int Elem)
{
//整型数据压栈操作实现
retum false;
}
由此可以看出,CStack<T>模板类传入不同的数据类型,可生成与此对应的不同类型的 CStack 堆栈类类型。这些工作都是在编译过程中实现的,即编译时的多态性。
请谨记
●C++语言不是C语言简单的扩充,C++语言和 C语言设计哲学理念也发生了根本性的变化,由面向机器设计理念转向了面向问题设计理念。
●C++语言对C 语言的扩充最为重要的两个概念是面向对象和泛型编程。
第一项了解C++程序的基本构成,快速入门指南4章内容讲解完毕
1.C++程序由哪些部分构成
2.既有面向过程,为何还要面向对象
3.掌握在 C++中如何使用C
4.C++比C加了什么