首页 > 代码库 > C++的const关键词的一些注记

C++的const关键词的一些注记

在c++中,const关键词出现在很多地方,有诸多的用途,也有很多的限制。

这里简单的列举一下const声明和定义的注意事项:(const对象定义时必须初始化,下面的例子只是说明一下const位置的含义)

  1. const出现在声明或者定义变量的类型的前面的时候,const修饰的是变量本身

    如:const char *value; //指针a指向const char类型,是指指针所指的变量不能改变,而指针本身的值可以改变

  2. 其它情况的const修饰其左边的符号:
    1. char *const value;//表明value指针是常指针,不可以改变它的指向,但是它所指向的对象可以改变
    2. char const* value;//表明value指针所指的对象是const char型,指针的指向可以改变(同const char* value;)
    3. const char* const value;//第一个const表明value所指的对象是const char型,第二个const表明指针本身是常指针,因此这里的value是指向常对象的常指针
    4. 上面的例子等价于:char const* const value;第一个const修饰char(表明指针所指的对象是const char型)第二个const表明value是指向const char的constant指针
  3. 可以用typedef来便于理解(从右边往左边读):

    例如:typedef char* a;

         a const b;

    b是const a类型,而a是指向char的指针,因此b是指向char的const 指针

  4. 综上呢,如果不能熟练的掌握const的位置和用法,将const修饰符放在类型的后面总是更容易理解的且不易出错的。
  5. 这个问题呢,是来自于C++primer 第4版的一个实例(是在看知乎的时候发现书中的这个实例被看的时候忽略了)

下面是这个实例(是讲函数模板和其特化)

1.  template<class T>2.  int compare(const T &a1, const T &a2)3.  {  4.      std::cout << "not specialization " ;5.   6.      if (a1 < a2)7.          return -1;8.      else if (a1 > a2)9.          return 1;10.     return 0;11.}12. 13.template<>14.int compare<const char*>( const char const* &a1, const char const*  &a2)15.{  16.     std::cout << "specialization " ;17.     return strcmp(a1, a2);}

这个模板很简单,就是比较两个形参的大小,然后返回比较结果。

然而如果将const char *的对象(如:"gaoduan")传递给该模板,则比较两个指针的地址,而不是我们所想要的结果,因此要对此模板进行特化,特化的方式很简单,以template<>开头,然后将模板中的类型参数T用具体的类型替代即可。(需要注意,特化的版本只会在实参精确匹配的时候调用,如此例中,若实参为char *或者char *const的时候都会调用原来的泛型版本,只有const char *的参数(注意,字面值常量可以和const型参数匹配)会调用特化类型的模板)

 

这里我们将const char *类型实例化,注意到函数形参是char const* const &类型

    这里应该这样理解:

  • 在原模板中,类型形参为T,函数形参为指向T的const引用
  • 特化模板中,类型形参为const char *,因此函数形参应为指向const char *类型的const引用

        因此,形参中应该有两个const,一个修饰引用,一个修饰char,

            因此,应该写作const char const* &(第一个const修饰最后的变量,即修饰引用,第二个const修饰char)

            或者,可以写作char const* const & 可以解读为:

typedef char const *A; A const&B;(A为指向const char的指针,B为指向A的常引用),因此也正确;