《C++ Templates中文版》——1.4 关于编程风格的一些说明

本节书摘来自异步社区出版社《C++ Templates中文版》一书中的第1章,第1.4节,作者: 【美】David Vandevoorde , 【德】Nicolai M. Josuttis,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.4 关于编程风格的一些说明

C++程序员的编程风格通常是互不相同的,我们也不例外:风格所涉及的问题包括在哪里加入分隔符、界定符(花括号、圆括号)等。我们会尽量保持一致的风格,但就当前的一些(特殊的)话题,偶尔也会有所例外。例如,在教程这一部分(第1部分),我们使用了大量的空格和具体的名称,是为了令代码更加形象;而在高级话题讨论部分(第4部分),我们就使用了比较紧凑的风格,这样显得更加适合话题的讨论。

关于“类型、参数、变量”的声明,我们希望你能注意一些稍微特殊的用法。显然,下面几种风格都是可能的:

void foo (const int &x);
void foo (const int& x);
void foo (int const &x);
void foo (int const& x);

对“常整数”而言,上面的几种用法虽然差别不大,但我们趋向于使用int const,而不使用const int。作出这个选择,主要有两个原因:首先,针对问题“什么是恒定不变的”,int const提供了很容易理解的答案。实际上,“恒定不变部分”指的是const限定符前面的部分。例如,尽管

const int N = 100;

等价于:

int const N = 100;

但是对于:

int* const book mark;  //指针不能改变,但指针指向的值可以改变

却没有相应的等价形式(就是说如果把const限定符放在运算符*的前面,与前者并不等价)。在这个例子中,我们只是说明了指针本身是个常量,而并没有说明这个int值(即指针指向的值)是个常量。

第2个原因涉及到使用模板时一个很常用的语法替换原则。考虑下面的两个类型定义[1]:

typedef char* CHARS;
typedef CHARS const CPTR; //指向char类型的常量指针

当我们用CHARS所代表的含义对它进行替换之后,第2个声明的含义是不变的:

typedef char* const CPTR;  //仍然是指向char类型的常量指针

然而,如果我们把const放在它所限定的类型的前面,那么这个原则就不再适用了。针对我们前面给出的两个类型声明,考虑下面的替换代码:

typedef char* CHARS;
typedef const CHARS CPTR; //指向char类型的常量指针

但如果我们替换掉CHARS之后,第2个声明却会导致不同的含义:

typedef const char* CPTR;  //指向常量char类型的指针

当然,同样的现象(规则)也适用于volatile限定符。

对于间隔符,我们决定在 & 符号和参数名称之间留出一个空格:

void foo (int const& x);

借助这种方法,我们同时也强调了:参数类型和参数名称是分离的。

显然,诸如下面的声明更容易令人混淆:

char* a, b;

上面代码中,如果根据C语言的规则,a是一个指针,而b是一个char类型的普通变量。为了避免产生这种混淆,我们尽量不在同一个语句中声明多个实体。

虽然这并不是一本介绍C++标准库的书,但我们在很多例子中都会用到标准库。在很多情况下,我们都使用了C++的特定头文件(例如我们使用< iostream >,而不是< stdio.h >)。唯一的例外情况是< stddef.h >,我们趋向于使用这个头文件,而不使用< cstddef >,从而也就不用给size_t和ptrdiff_t添加std:: 名字空间限定;另外,< stddef.h >具有更好的可移植性;而且,使用std::size_t替换size_t并不能得到任何好处。

上一篇:好文转载:Linux内核中的中断栈与内核栈的补充说明


下一篇:迭代器和生成器