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