高质量C++编程指南学习笔记5-6章---thanks to林锐

第五章     常量

51常量类型

         C语言用#define啦定义常量(称为宏常量)C++除了#define外还可用const来定义常量(称为const常量)

         const常量有数据类型,而宏常量没有数据类型。编译器可对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查。所以在C++中只使用const常量而不使用宏常量。

52常量定义规则

   【规则5-2-1】需要对外公开的常量放在头文件中,不需对外公开的常量放在定义文件的头部。为便于管理,可把不同模块的常量集中存放在一个公共的头文件中。

53类中的常量

         有时希望某些常量只能在类中有效。因#define定义的宏常量是全局的,于是想当然的认为该用const修饰数据成员来实现。但const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的,因类可创建多个对象,不同的对象其const数据成员的值可不同。头文件中不能初始化const数据成员,只能在构造函数中初始化。

         怎么才能建立在整个类中都恒定的常量呢?应该用类中的枚举常量来实现。枚举常量不会占用对象的存储空间,它们在编译时被全部赋值。缺点是:它的隐含数据类型是整数,其最大值有限,且不能表示浮点数。

第六章     函数设计

函数设计,函数该怎么设计,参数、返回值和实现。

C中函数参数和返回值的传递方式:值传递和指针传递。C++中多了引用传递。引用传递的性质象指针传递,而方式去像值传递。

61参数的规则

   【规则6-1-1】参数书写要完整。不要只写参数类型忽略参数名字,若无参数用void填充。

   【规则6-1-2】参数命名要恰当,顺序要合理。一般,应将目的参数放在前面,源参数放在后面。

   【规则6-1-3】若参数是指针,且仅作输入用,则应在类型前加const,以防止该指针再函数体内被以外修改。

   【规则6-1-4】若输入参数以值传递的方式传递对象,则宜改用”const&”方式来传递,这样可省去临时对象的构造和析构过程,从而提高效率。

   【建议6-1-1】尽量将参数个数控制在5个以内。

   【建议6-1-2】尽量不要使用类型和数目不确定的参数。C标准库函数printf是采用不确定参数的典型代表,其原型为:int printf(const char *format[,argument])这种风格的函数在编译时丧失了严格的类型安全检查。

62返回值的规则

   【规则6-2-1】不要省略返回值的类型。因不加类型说明的函数,C默认返回整型;C++有严格的类型检查,不会出现上述情况。C++调用C时会混淆。

【规则6-2-2】函数名字与返回值类型在语义上不可冲突。违反这条规则的典型代表是C标准库函数getchar。函数名字时取得char类型,但实际返回int类型。int getchar(void)

【规则6-2-3】不要将正常值和错误标识混在一起返回。正常值用输出参数获得,而错误标识用return语句返回。

C标准库函数的设计者为什么要将getchar声明为令人迷惑的int型呢?正常情况,getchar的确返回单个字符。但如果getchar碰到文件结束标识或发生读错误,它必须返回一个EOF。为了区别于正常的字符,只好将EOF定义为负数(通常是-1)。因此函数getchar就成了int型。

为了避免出现上述情况,应将正常值和错误标识分开。getchar可改为BOOL GetChar(char *c)

【建议6-2-1】有时候函数原本不需要返回值,但为了增加灵活性如支持链式表达,可以附加返回值。

strcpystrSrc拷贝到参数strDest中,同时函数返回值又是strDest。这并非多次一举,可获得如下灵活性:char str[20]; int length = strlen( strcpy(str,”Hello World”));

【建议6-2-2】若函数的返回值是一个对象,有些场合用“引用传递”替换“值传递”可以提高些效率。而有些场合只能用“值传递”,否则会出错。

63函数内部实现

   【规则6-3-1】在函数体的“入口处”,对参数的有效性进行检查。正确使用“断言”(assert)来防止此类错误。

   【规则6-3-2】在函数体的“出口处”,对return语句的正确性和效率进行检查。注意事项如下:

Ø  return语句不可返回指向“栈内存”的“指针”或“引用”,因该内存在函数体结束时被自动销毁。

Ø  若函数值返回是一个对象,要考虑return语句的效率。例如:return String(str1+str2);这是临时对象的语法,表示“创建一个临时对象并返回它”。不要以为它与“先创建一个局部对象temp并返回它的结果”是等价的。例如:String temp(s1+s2); return temp;此代码发生三件事。首先temp对象被创建,同时完成初始化;然后拷贝构造函数把temp拷贝到保存返回值的外部存储单元中;最后,temp在函数结束时被销毁(调用析构函数)。然而“创建一个临时对象并返回它”的过程是不同的,编译器直接把临时对象创建并初始化在外部存储单元中,省去了拷贝和析构的花费。类似,不要将return int(x+y);写成int temp = x+y; return temp;因内部数据类型的变量不存在构造和析构函数,显然该“临时变量的语法”不会提供多少效率,但程序更加简洁易读。

64其他建议

   【建议6-4-1】函数功能要单一,不要设计多用途的函数。规模要小,尽量在50行内。

【建议6-4-2】尽量避免函数带有“记忆”功能。函数的static局部变量是函数的“记忆”存储器。尽量少用static局部变量。

【建议6-4-3】不仅要检查输入参数的有效性,还要检查通过其他途径进入函数体内的变量的有效性,如全局变量、文件句柄等。

65使用断言

         程序一般分Debug版本和Release版本。断言assert是仅在Debug版本起作用的宏。为了不在程序的Debug版本和Release版本引起差别,assert不应该产生任何副作用。所以assert不是函数,而是宏。

   【规则6-5-1】使用断言捕捉不应该发生的非法情况。不要混淆非法情况与错误情况的区别,后者是必然存在的且一定要做出处理的。

   【规则6-5-2】在函数入口处,使用断言检查参数的有效性。

   【规则6-5-3】在编写函数时,要进行反复考查,并且自问“我打算做哪些假定?”一旦确定了的假定,就要用断言对假定进行检查。----------不懂。

66引用与指针的区别

         引用的一些规则:

Ø  引用被创建的同时必须被初始化(指针则可在任何时候被初始化)

Ø  不可能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL)

Ø  一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)

引用的主要功能是传递函数的参数和返回值。

值传递                                                    指针传递                                                  引用传递

void Func1(int x)                void Func1(int *x)                void Func1(int &x)

{                                                                  {                                                                     {

         x = x + 10;                                               (*x) =(* x) + 10;                                                       x = x + 10;

}                                                                  }                                                                     }

int n = 0;                                                   int n = 0;                                                      int n = 0;

Func1(n);                                                  Func1(&n);                                                 Func1(n);

cout<<n;//n = 0;                                     cout<<n;//n = 10;                                     cout<<n;//n = 10;

         由上可看出“引用传递”的性质像“指针传递”,而书写方式像“值传递”。实际上,“引用”可做的任何事情“指针”都可做,为什么还要“引用”呢?答案是“用适当的工具做恰如其分的工作”。指针功能强大,但非常危险。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值