const对C++成员函数的修饰分为三种:1. 修饰参数;2. 修饰返回值;3. 修饰this指针。简述一下知识点如下,以后找功夫再完善。

1. 对函数参数的修饰。

  1)const只能用来修饰输入参数。输出型参数不能用const来修饰。

  2)如果输入参数采用“指针传递”,那么加const修饰可以防止意外地改动该指针,起到保护作用。

  3)如果输入参数采用“值传递”,函数将产生临时变量(局部变量),复制该参数的值并且压入函数栈。函数中使用该参数时,访问的是函数栈中临时变量的值,原变量无需保护,所以不要加const修饰。

  4)基本变量类型的参数作为“值传递”的输入参数,无需采用引用。自定义变量类型(class类型,struct类型)参数作为“值传递”的输入参数,最好采用"const+引用"格式,即 void func(const A& a)。原因是自定义变量类型作为值传递时,设计创建临时变量,构造,复制,析构,这些过程很消耗时间。

  从函数栈的基本原理考虑原因。我们知道,函数在被调用时,会为创建各个实参创建临时变量并将其压入函数栈。如果是基本变量类型,则压入函数栈的临时变量中存储的是实参的副本;如果是自定义变量类型,则会在堆上创建该类型实例,复制该实参到堆上,然后将堆上该实例的地址压入函数栈;如果是指针,则会将指针地址的副本(其实也可以认为这个保存这个指针的变量是基本变量类型)压入函数栈。

  也就是说,函数栈上要么保存的是一个基本类型参数的副本,要么是个顶层指针。对于函数栈上保存的参数,实参的副本可以作为一个普通的局部变量,是可以修改值的,而对于指针变量,其可以视为顶层指针,本身的值不可以修改,但其指向的值可以修改。

  故而可知,对于基本变量类型,函数内部操作的是函数栈上的副本,不会对原值产生影响,对于类类型(非指针输入性参数),操作的也是函数栈上的地址指向的实例副本,同样不会对原值产生影响;而对于指针,函数内部虽然改变不了指针变量保存的指针值(该指针为顶层指针),但该指针却指向的是原值的地址,故而能修改原值。

  对于引用,a)引用只是变量的一个别名,引用指向元变量内存地址,不会进行新的内存分配和变量的拷贝;b)引用声明后必须马上初始化;c)引用一经定义,不能改变其值,也就是不能再作为其它变量的引用; d)通过引用可以完全操作原变量。

  可以看出,当占空间很大的变量作为输入型实参时,很适合用引用传递。因为用引用传递时,只是传递变量本身的一个别名,不会进行新变量的内存分配,构造,赋值,析构等操作。

  如果函数中不允许改变该实参,那么就应该在引用参数上加const修饰。

  基于上述考虑。const修饰输入型参数时,只需要修饰指针类型和引用类型即可(虽然不是强制,但对于输入型指针或者引用参数用指针修饰应该成为一种习惯)。

  同时,这也说明一个编程时应该养成的习惯,对于输入型参数,应该在函数起始位置定义一个局部变量接收该输入型参数,而不是直接使用。

2.  对返回值的修饰。

  这个应用比较少。大部分返回值采用的时“值传递”。如果将返回值修饰为const,那么接收返回值的变量也必须定义为const。

 3. 对this指针的修饰。

  我们知道,c++成员函数在编译时候,会传入一个this指针,指向实例本身。这个this指针默认实际上是个顶层指针。即如果有classA,那么这个指针其实类似如下的定义:

  classA * const this;

  即this指针指向实例本身并且不可以修改,但可以通过this指针修改其指向的成员变量。在成员函数内访问成员变量m_var,实际上时如下形式方位的:

  this.m_var;

  如果我们设计一个成员函数时,不想让其修改成员变量,那么就应该将this指针定义为底层指针。c++定义的方式就是在函数签名后面加上const,即

  void func(const A& a, int b, const int* c, int* d)const;

  显然,上述成员函数中,a为const引用传递,不可以改变原值;b为值传递;c为const指针传递,不可改变原值;d为输出参数,可以改变原值。而该函数为const成员函数,不可以修改成员变量值。

  以下是const成员函数注意的几点

  1)const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数.即对于class A,有

  const A a;

  那么a只能访问A的const成员函数。而对于:

  A b;

  b可以访问任何成员函数。

  2)const对象的成员变量不可以修改。

  3)mutable修饰的成员变量,在任何情况下都可以修改。也就是说,const成员函数也可以修改mutable修饰的成员变量。c++很shit的地方就是mutable和friendly这样的特性,很乱。

  4)const成员函数可以访问const成员变量和非const成员变量,但不能修改任何变量。检查发生在编译时。

  5)非const成员函数可以访问非const对象的非const数据成员、const数据成员,但不可以访问const对象的任意数据成员。

  6)const成员函数只是用于非静态成员函数,不能用于静态成员函数。

  7)const成员函数的const修饰不仅在函数声明中要加(包括内联函数),在类外定义出也要加。

  8)作为一种良好的编程风格,在声明一个成员函数时,若该成员函数并不对数据成员进行修改操作,应尽可能将该成员函数声明为const 成员函数。

const关键字对C++成员函数的修饰的更多相关文章

  1. 用 const 限定类的成员函数

    类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变. 在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 const,而对于 ...

  2. const用在成员函数之后的情况

    常成员函数         使用const关键字进行说明的成员函数,称为常成员函数.只有常成员函数才有资格操作常量或常对象,没有使用const关键字说明的成员函数不能用来操作常对象.常成员函数说明格式 ...

  3. C++中const关键字的使用方法,烦透了一遍一遍的搜,总结一下,加深印象!!!

    之前一直在学习C/C++,关于const的使用,这里出现一点,那里出现一点.知识用时方恨少,这一段时间正好各种笔试题,其中关于const的用法也是层出不穷,所以疲于在书本上各种翻,这里汇总一下,加深自 ...

  4. const成员函数和mutable关键字

    一.const成员函数 class MyClass { public: void fun() const { } private: int m_nValue; } const成员函数内不能修改成员变量 ...

  5. const 修饰成员函数 前后用法(effective c++ 03)

    目录 const在函数后面 const修饰成员函数的两个作用 const在函数前面 总结 const在函数后面 类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态 ...

  6. 第24课.经典问题解析(1.析构函数的顺序;2.const修饰对象;3.成员函数,成员变量是否属于具体对象)

    1.当程序中存在多个对象的时候,如何确定这些对象的析构顺序? 单个对象 单个对象创建时构造函数的调用顺序 a.调用父类的构造函数 b.调用成员变量的构造函数(调用顺序与声明顺序相同) c.调用类自身的 ...

  7. 类中用const限定的成员函数

    本文转自http://blog.csdn.net/whyglinux/article/details/602329 类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非 ...

  8. (转)函数后面加const--C++ const成员函数

    类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变. 在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 const,而对于 ...

  9. C++之const类成员变量,const成员函数

    const修饰类的成员函数 const修饰变量一般有两种方式:const T *a,或者 T const *a,这两者都是一样的,主要看const位于*的左边还是右边,这里不再赘述,主要来看一下当co ...

随机推荐

  1. ubuntu16.04下安装pcl点云库

    安装依赖项 sudo apt-get update sudo apt-get install git build-essential linux-libc-dev sudo apt-get insta ...

  2. 洛谷P3067 平衡的奶牛群 [USACO12OPEN] meet-in-the-middle

    正解:搜索 解题报告: 先放下传送门QwQ 这题就,双向搜索经典题鸭 首先dfs应该挺好想到的我jio得?就是我们不用记录左右分别得分多少只要记下差值就好了嘛能get? 然后就先搜左边,记录下每个得分 ...

  3. 小米范工具系列之十:小米范SSH批量命令执行工具

    小米范SSH批量命令执行工具的主要功能是自动登录多台机器,并执行指定的命令,比如批量抓取shadow.批量获取系统版本.或者做基线时批量抓取配置等. 此工具使用java 1.8以上版本运行. 界面如下 ...

  4. My Emacs Writing Setup

    My Emacs Writing Setup Table of Contents 1. About this Document 1.1. Related Materials 1.2. Change H ...

  5. jquery序列化表单以及回调函数的使用

    在开发项目中.将前台的值传给后台,有时的JSP表单中的值有一两个,也有所有的值,假设这时一个个传,必然不是非常好的办法,所以使用jQuery提供的表单序列化方法,能够非常好的解决问题.同一时候能够封装 ...

  6. 使用 Nginx 提升网站访问速度

    使用 Nginx 提升网站访问速度 http://www.ibm.com/developerworks/cn/web/wa-lo-nginx/ Nginx 简介 Nginx ("engine ...

  7. 7.如何将python脚本打包为exe形式

    先安装pyinstaller,pip install pyinstaller 然后 pyinstaller -F combine.py打包即可

  8. 5.4 Components -- Wrapping Content in A Component(在组件中包裹内容)

    1.有时候,你可能希望定义一个模板,它包裹其他模板提供的内容. 例如,假设我们创建一个blog-post模板,我们可以使用它来展现一个blog post: app/components/blog-po ...

  9. hdu5139

    这题需要我们计算 这个 因为n<10000000空间过大 那么我们可以计算出 当n可以被10整除的时候我们就将n/10记录下来当我们要查询的时候去暴力计算他们与整十之间的数去暴力去做就好了 这个 ...

  10. python中模块导入问题(已解决)

    想在python中导入request包: 无此模块,于是先安装requests包: 但是提示"Requirement already satisfied".在提示的相应目录里,找到 ...