转换为ANSI/ISO 标准c++

    最近在复习C++,也注意到了 C++ 11新标准的一些动向,微软的msdn也推出了一系列的《welcome back to modern C++ 》的文章,用C++之父Stroustrup的话说,“C++ 11 像一门全新的语言”,(其实真有,D语言基本就是全新的C++微笑),去年研一,花了一个暑假,把《C++ primer plus》厚厚的一本书完完整整地看完了,之后对C++产生了无限的兴趣,这里主要是把《C++ primer plus》后面附录的一篇好文章摘录如下,算是我隔了好久,重新开始写新的博文 :

1.1 使用一些预处理器编译指令的替代品

1.1.1使用const而不是#define来定义常量

        C使用预处理器来创建常量的符号名称:

#define MAX_LEN


        C++ 推荐使用const变量来替代:

const  int  MAX_LEN =100;

        使用const的方法优点很多:首先,使用#define时,必须在数字后面加各种后缀来指出除char,int或double之外的类型。例如 ,使用100L表示long 类型;使用3.14F表示float类型。更重要的是,相比#define,const可很方便的用于复合类型,如:

const  int base_vals[]={100,200,300,400,500};
const string ans[3]={"yes","no ","maybe "};

        此外,const标识符遵循变量的作用域规则,因此,可以创建作用域为为全局,名称空间或数据块常量。不必担心其定义与程序的其他地方使用的全局变量冲突,如下面的代码:

#define n 5
const int dz =12;
...
void  fizzle()
{
 	int n;  //ERROR:预处理器将把此处替换为 int 5 
	int dz;
...
}


        最后,相比C语言中的const,C++版本的const变量默认为内部链接性,这意味着,可将const定义放在工程中的各种文件使用的头文件中而不会产生编译错误,更多const的用法可以看这里

        当然在控制何时编译头文件方面,#define编译指令仍然很有帮助:

//blooper.h
#ifndef _BLOOPER_H_
#define _BLOOPER_H_
// code goes here
#endif


        另外,在有一组相关的整型常量时--使用枚举enum类型可能是更好的选择

enum{LEVEL1=1, LEVE2=2,L EVEL3=4, LEVEL4=8};


1.1.2 使用inline而不是#define来定义小型函数

        在创建类似于内联函数的东西时,传统的C语言方式是使用一个#define宏定义:

#define Cube(X) X*X*X

        这将导致预处理器进行文本置换,而由于不是真正的传递参数,因此使用这种宏常常导致意外、错误的结果:

y=Cube(x) ;
y=Cube(x+ z++); // 替换出错,得加大量的括号来避免,如:
#define Cube(x) ((x)*(x)*(x)) //注意,Z++的问题还是不能解决


 

        C++是用inline关键字来标识内联函数,C++内联函数可以是常规函数,也可以是类方法;

        #define宏的一个优点是,它是无类型的,可任意替换;但这一点可以通过创建内联模板来使函数独立于类型,同时传递参数。

1.2 使用函数原型

         注意:C++中,函数原型是必不可少的;

        应尽量在函数原型和函数头中使用const,具体的说,对于表示不可修改的数据的指针参数和引用参数,应尽量使用const。这不仅使编译器能够捕获修改数据的错误,也使函数更为通用。也就是说,接受const指针或引用的函数能够同时处理const数据和非const数据,而不使用const指针或引用的函数只能处理非const的数据。

1.3类型转换

        Stroustrup对C语言的抱怨之一就是其无规律可循的类型转换操作符,此外C语言不能防止将一种类型的指针转换为另一种完全不相干的类型指针,这也是极不安全的。而标准的C++提供了新的严格类型转换操作符:

dynamic_cast
static_cast
const_cast
reinterpret_cast


        这方面,《C++ primer plus》基本上讲的非常不清楚,《C++编程思想》把概念进一步解释的更清楚些。

        因此,在执行涉及到指针的类型转换时,应尽可能使用上述操作符之一。这样做不但可以指出类型转换的目的,并可以检查类型转换是否按照预期的那样使用的。

1.4 逐渐熟悉C++特性

        如果使用的是malloc()和free(),请改用new和delete;如果是使用setjmp()和longjmp() ,(说实话,这个还真没用过,C语言学的,太汗了~)处理错误,则请改用try、throw 、和catch。另外,对于表示true和false的值,应将其类型声明为bool。

1.5使用新的头文件

        注意:除了名称的改变,相比老式头文件,则应当改用新名称。这样做不仅仅是形式上的改变,因为新版本有时增加了新的特性。另外,新的头文件包含名称空间。

1.6使用名称空间

    

1.7使用autoptr模板   

        每个new都应与delete配对使用。如果使用new的函数由于引发异常而提前结束,将导致问题。使用autoptr对象跟踪new创建的对象将自动完成delete操作。

1.8使用string类

        传统的C风格字符串深受不是真正的类型之苦。可以将字符串存储在字符数组中,也可以将字符数组初始化为字符串。但不能使用赋值操作符将字符串赋给字符串,而必须使用strcpy()或strncpy()。不能关系操作符来比较C风格字符串,而必须使用strcmp() (使用操作符倒是不会出现句法错误,程序将比较字符串的地址,而不是字符串的内容)。

        而string类使得能够使用对象来表示字符串,并定义了赋值操作符、关系操作符和加法操作符(用于拼接)。此外,string类还提供了自动内存管理功能。不会提前出现字符串截短的情况。

        string类不仅提供了一组设计良好的方法来处理与字符串相关的工作(如查找子字符串)。而且与STL兼容,因此可将STL算法用于string对象。

1.9使用STL

         一个明显的好处是,如用你声明一个double或者string对象数组,不如创建vector<double>对象或者vector<string>对象。这样做的好处与使用string对象类似。赋值操作符已被定义,因此可以使用赋值操作符将一个vector对象赋给另一个vector对象。内置的内存管理功能使得当使用pushback()方法在vector对象中添加元素时,其大小将自动调整。当然,还可以根据实际需要来使用其他有用的类方法和通用算法。

        如果需要链表、双端队列(或队列)、堆栈 、常规队列、集合或者映射,应使用STL,它提供了有用的容器模板。算法库使得可以将矢量的内容轻松地复制到链表中,或将集合的内容同矢量比较。这种设计使得STL成为一个工具箱,它提供了基本部件,可以根据自己的需求进行装配。

        在设计内容广泛的算法库时,效率是一个主要的设计目标,因此只需要完成少量的编程工作,便可以得到最好的结果。另外,实现算法时用到了迭代器的概念,这意味着这些算法不仅可以用于STL容器,也可以用于传统的数组。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值