const读书笔记

Const 的使用读书笔记

Const的主要主要用法有:

常变量: const 类型说明符 变量名

常引用: const 类型说明符 &引用名 
常对象: 类名 const 对象名
常成员函数: 类名::fun(形参) const
常数组: 类型说明符 const 数组名[大小]
常指针: const 类型说明符* 指针名 ,类型说明符* const 指针名

  • 常变量

      例如:const int a;  或  int const a; 在c语言中声明时必须进行初始化,C++中则没有这个限制。C 标准中,const 定义的常量是全局的,C++中视声明位置而定。

  • 指针常量和常量指针

    const int *x; 指向常整型的指针,x所指向的数据不能被修改

    int *const x; 指向整形的常量指针,x不能指向其它地址;

    const int *const x;指向常整型的常量指针,x所指向的数据不能被修改,同时x自身也不能指向其他地址空间。

    对于const int *x,虽然不能直接修改*x的值,但是我们可以通过下面的方式来修改:

int i = 10;

const int *x = &i;

    int *p = (int *)x;

    *p = 11;

    //此时i=11; *x= 11;


  同样在函数参数中使用指针常量和常量指针的意义是一样的。   Void f(const char *p);  void f(char *const p);

   

  如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const 修饰,否则该参数将失去输出功能。const 只能修饰输入参数:如果输入参数采用“指针传递”,那么加const 修饰可以防止意外地改动该指针,起到保护作用。例如StringCopy 函数:

void StringCopy(char *strDestination, const char *strSource);


其中strSource 是输入参数,strDestination 是输出参数。给strSource 加上const修饰后,如果函数体内的语句试图改动strSource 的内容,编译器将指出错误。

  如果输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加const 修饰。例如不要将函数void Func1(int x) 写成void Func1(const int x)。同理不要将函数void Func2(A a) 写成void Func2(const A a)。其中A 为用户自定义的数据类型。

  对于非内部数据类型的参数而言,象void Func(A a) 这样声明的函数注定效率比较底。因为函数体内将产生A 类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。

为了提高效率,可以将函数声明改为void Func(A &a),因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。但是函数void Func(A &a) 存在一个缺点:

    “引用传递”有可能改变参数a,这是我们不期望的。解决这个问题很容易,加const修饰即可,因此函数最终成为void Func(const A &a)。以此类推,是否应将void Func(int x) 改写为void Func(const int &x),以便提高效率?完全没有必要,因为内部数据类型的参数不存在构造、析构的过程,而复制也非常快,“值传递”和“引用传递”的效率几乎相当。

  • 常量引用
    引用(reference)就是对象的另一个名字,引用主要用作函数的形式参数。常量引用表示不能通过改引用去修改对应内存的内容。
int i = 10;

const int &j = i;  //不能通过j改变i的值

 

void func(const int& i)
{
     i = 100; // 错误!不能通过i 去改变它所代表的内存区域。
} 
  • 常量函数

  在一个函数的签名后面加上关键字const 后该函数就成了常量函数。对于常量函数,最关键的不同是编译器不允许其修改类的数据成员

             

class Test
{
   public:
   void func() const;
private:
   int intValue;
};
void Test::func() const
{
  intValue = 100;
}


  上面的代码中,常量函数func 函数内试图去改变数据成员intValue的值,因此将在编译的时候引发异常。

  • 常量对象
    如果我们把一个类定义为常量,我们的本意是希望他的状态(数据成员)不会被改变。那么,如果一个常量的对象调用它的非常量函数会产生什么后果呢?常量对象的状态不允许被修改,又因为非常了得函数可以修改类的成员,因此,通过常量对象调用非常量函数时将会产生语法错误。
  • 常量返回值
    这里就不总结了,具体的可以去看参考文档。

Const 常量定义相对于define宏定义的优势

       const定义的常量具有数据类型,定义数据类型的常量便于编译器进行数据检查,使程序可能出现错误进行排查。define进行宏定义的时候,不会分配内存空间,编译时会在main函数里进行替换,只是单纯的替换,不会进行任何检查,比如类型,语句结构等,即宏定义常量只是纯粹的置换关系。

参考资料:

[1] http://www.phpweblog.net/maple094/archive/2008/05/30/4054.aspx

[2] http://social.msdn.microsoft.com/Forums/vstudio/zh-CN/b882d9d0-cd67-4eca-930c-7061133c50e6/faq225-const-int-int-const-const-int-const

[3] http://blog.csdn.net/ego51up_liyanhong/article/details/8624811

[4]http://www.360doc.com/content/11/0901/11/255982_144947210.shtml#

原文地址:https://www.cnblogs.com/Jason-Damon/p/3371072.html