2007年7月21日星期六

C++语言对C语言在非面向对象方面的增强

  C++除了继承了传统C语言中的精华,并增加了许多的面向对象的特征之外,还在非面向对象方面对C语言进行了增强。本节将对C++语言在非面向对象方面的增强特征及功能作一个简要介绍。
1) C++提供了单行注释方式

  在传统的C语言中提供了块注释方式,其形式如下:
  /* explanation sentence */

  而在C++中,除了保留了块注释方式外,还增加了一种更为方便的单行注释方式,其形式如下:
  // explanation sentence


2) 更为灵活的变量说明

  在传统的C语言中,局部变量的说明必须放在可执行代码的前面,数据说明语句和可执行语句的混合将引起编译错误。而在C++中,可以在程序代码块的任何地方进行局部变量的说明,所说明变量的作用域是从对该变量进行说明的地方开始到该变量所在的最小分程序的末尾。


3) 结构、联合和枚举名可直接作为类型名使用

  在C语言中,在对结构、联合和枚举类型进行定义后,要生成该结构、联合或枚举类型的变量,必须使用如下形式:
  struct struct_name obj_name;
  union union_name obj_name;
  emun emun_name obj_name;

  即必须在所说明的结构、联合或枚举名的前面加上说明其所属类型的标识符。而在C++中,在对结构、联合和枚举类型进行定义后,该结构、联合或枚举名便可以作为类型名使用,可以直接用它来进行对象的定义。


4) 枚举类型与整型的关系

   在C语言中,枚举值与整型值之间可以相互转换使用。而C++的类型检查则比C要严格,枚举值将被自动转化为整型值使用,但将整型值转化为枚举值则需要进 行强制类型转换,否则会出现编译错误。如下面的一段代码,在C语言中都是可以接受的,但某些语句在C++中则会引起错误。
  enum Name {John, Mike, Rose, Joan};
  enum Name person1 = John; //This is OK!
  enum Name person2 = person1; //This is also OK!
  enum Name person3 = 1; //This is an error in C++!
  enum Name person4 = (enum Name)1; //This is OK!


5) C++增加了无名联合类型

  无名联合是C++中提供的一种特殊联合,可以用来说明一组无标记名的、共享同一内存地址的数据项。例如:

union
{
int i;
float f;
};

无名联合可以通过使用其中数据项名字直接进行访问。


6) 作用域限定运算符::

  作用域限定运算符::用于对当前作用域之外的同名变量进行访问。如在下面例子中,我们在局部变量var的作用域内使用::var来实现对全局变量var的访问。

#include

int var;

void main()
{
float var;
var = 3.14; //局部变量var
::var = 6; //全局变量var
cout << "local variable var = " << var << "\n";
cout << "global variable var = " << var << "\n";
}
该程序的输出结果如下:
local variable var = 3.14
global variable var = 6


7) 函数调用时的参数传递方式

  在C语言中,函数调用时的参数传递是用按值传递方式进行的,在子函数中对形参的改变并不引起实参的数值改变。而在C++中,函数调用时的参数传递是用按址传递方式进行的,形参和实参所指向的是同一内存区域的内容,因此在子函数中对形参的修改将会导致实参的数值变化。


8) 增强了类型转换方式

  在C++中,除了保留了传统C语言的强制类型转换方式外,还可以将类型名作为函数名使用,这将大大提高了程序的可读性。例如:

float f = 0.01;
long l = (long)f;
long k = long(f);


9) void类型

  在C++中,void类型指针是可以与任何类型指针相匹配的指针,void类型指针可以被赋给任何类型的指针,从而可以避免许多无用的类型转换。而void型函数是无返回值的函数,它可以限制函数返回一个无用的int型数值。


10) 关键字const

   在C++中,关键字const用于将一个标识符说明为常量,即其值在程序的运行过程中不变的量,程序不能以任何方式对其进行修改。而C++中的 const与C语言中的#define是有区别的:const所说明的常量是有内存单元与之对应的量,在程序编译时其值还不能确定;而#define所说 明的是在编译时便能确定其数值的常量。
  关键字const也可以用来修饰函数参数表中的某些参数,用以保证被修饰的参数对应的实参在该函数内部不被改动。
  当关键字const用来修饰指针时,根据使用的形式不同,它可以冻结指针所指向的变量、冻结指针本身或同时冻结指针及其所指向的变量,如下所示:

const char *name = "Mike"; //冻结指针所指向的变量
char *const name = "Mike"; //冻结指针本身
const char *const name = "Mike"; //同时冻结指针及其所指向的变量


11) 类型兼容性

  C++的类型匹配检查比C更为严格。在C中,长度同为1字节的char、unsigned char、signed char型变量在相互赋值是可以不进行强制类型转换,而在C++中,则必须进行强制类型转换,否则会出现编译错误。在类型兼容型方面的增强将大大提高程序的可移植性。


12) 字符常量的大小

  在C语言中,字符常量是按照整型来进行处理的,它们的长度都是2byte。而在C++中,整型变量的长度仍为2byte,但字符常量的长度只有1byte,这使得C++程序占用内存空间更为节约,程序运行的效率更高。


13) new和delete

  C++为了提高内存管理上的灵活性,提供了动态内存分配和释放的操作符new和delete,用来增强C语言中原有的函数malloc()和free()。


14) 函数原型

  在C++中,函数原型说明要求给出该函数的参数类型,这比传统的C语言的函数原型说明更有利于编译系统检查非法参数调用,可以避免出现一些难于发现和调试的错误。


15) 内联函数(inline)

  C++提供了内联函数,使用内联函数可以节约函数调用时保留现场所需的系统开销,提高程序执行效率。同时,由于内联函数的使用将增大了程序的代码段,因此建议在使用时充分权衡系统开销和程序代码段长度的关系,谨慎使用。


16) 缺省函数参数

  在C++的函数调用时,可以缺省函数的参数。但是要使用缺省函数参数,必须在函数定义时为该参数赋一缺省值,且所缺省的参数的顺序只能是从右到左,不能随意缺省。请看以下例子:

int function(int a = 0; int b = 1; int c = 2);
{
……
}
以下函数调用都是合法的:
function(); //equal to function(0, 1, 2)
function(12); //equal to function(12, 1, 2)
function(12, 13); //equal to function(12, 13, 2)
function(12, 13, 14);
而以下函数调用则是非法的:
function( ,13, 14);
function(12, , 14);


17) 函数返回值

  在C++中,任何说明为非void类型的函数都需要指定一个相应类型的返回值,否则在程序的编译时会产生警告错误。

没有评论: