templates(0.1)

每一位 C++ 程序员都有自己的一套编程风格。这就引来了各种问题:哪儿应该 插入空白符号、怎么摆放分隔符(大括号、小括号)…等等。我们尽量保持全书风格一致, 当然有时候我们也对特殊问题作出让步。例如在教本(初阶)部份我们鼓励以空白符号和较具体的命名方式提高程序可读性,而在高阶主题中,较紧凑的风格可能更加适宜。

我们有一个他人不太常用的习惯,用以声明类型(types)、参数(parameters)和变量(variables), 希望你能多加注意。下面数种方式无疑都是合理的:

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

尽管较为罕见,我们还是决定在表达「固定不变的整数」(constant integer)时使用 int const而不写成 const int。这么做有两个原因,第一,这很容易显现出「什么是不能变动的(what isconstant)」。不能变动的量总是 const 饰词之前的那个东西。尽管以下两式等价:

const int N = 100; //一般人可能的写法

int const N = 100; //本书习惯写法

但对以下述句来说就不存在所谓的等价形式了:

int* const bookmark; // 指针 bookmark 不能变动,但指针所指内容(int)可以变动

如果你把 const 饰词放在运算符 * 之前,那就改变了原意。本例之中不能变动的是指针本身,不是指针所指的内容。

第二个原因和语法替换原则(syntactical substitution principle)有关,那是处理 template 程序代码时常会遭遇的问题。考虑下面两个类型定义:

typedef char* CHARS;
typedef CHARS const CPTR; // 一个用以「指向 chars」的 const 指针,如果我们做文字上的替换,把 CHARS 替换为其代表物,上述第二个声明的原意就得以保留:
typedef char* const CPTR; // 一个用以「指向 chars」的 const 指针。然而如果我们把 const 写在被修饰物之前,上述规则便不适用。考虑上述声明的另一种变化:

typedef char* CHARS;
typedef const CHARS CPTR; // 一个用以「指向 chars」的 const 指针,现在,对 CHARS 进行文字替换,会导出不同的含义:
typedef const char* CPTR; // 一个用以「指向 const chars」的指针

面对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::前缀词。这样做更具可移植性,而且 std::size_t 并不比 size_t 多出什么好处。

#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
    const int N=100;
    int const N=100; //二者等价
    int mark=0;
    //1
    int* ref_mark=&mark;
    int* const book1=ref_mark;//指针book1是个常量,并没有说明这个指针指向的int值是个常量
    const int* book2=ref_mark;//指针book2是个指针类型的常量
    cout<<"N1:"<<N1<<endl;
    cout<<"N2:"<<N2<<endl;
    *book1=10;
    cout<<*book1<<endl;
    *book2=20;
    /*
    |error: assignment of read-only location ‘* book2’|
    const int *book2=ref_mark
    */
    cout<<*book1<<endl;
    cout<<*book2<<endl;
    //2
    typedef char* CHARS;
    
    typedef CHARS const CPTR;    
    //替换后
    typedef char * const CPTR;
    //仍然是指向char类型的常量指针
    
    typedef const CHARS CPTR;   
    //替换后
    typedef const char * CPTR;
    //是指向char类型的指针

}
原文地址:https://www.cnblogs.com/jianfengyun/p/3714569.html