转自:http://blog.csdn.net/lihao21/article/details/8634876

我们知道,在C++中,若一个变量声明为const类型,则试图修改该变量的值的操作都被视编译错误。例如,

[cpp] view plain copy

 

  1. const char blank = ‘’;
  2. blank = ‘\n’;  // 错误

面向对象程序设计中,为了体现封装性,通常不允许直接修改类对象的数据成员。若要修改类对象,应调用公有成员函数来完成。为了保证const对象的常量性,编译器须区分不安全与安全的成员函数(即区分试图修改类对象与不修改类对象的函数)。例如,

[cpp] view plain copy

 

  1. const Screen blankScreen;
  2. blankScreen.display();   // 对象的读操作
  3. blankScreen.set(‘*’);    // 错误:const类对象不允许修改

在C++中,只有被声明为const的成员函数才能被一个const类对象调用。

要声明一个const类型的类成员函数,只需要在成员函数参数列表后加上关键字const,例如,

[cpp] view plain copy

 

  1. class Screen {
  2. public:
  3. char get() const;
  4. };

在类体之外定义const成员函数时,还必须加上const关键字,例如

[cpp] view plain copy

 

  1. char Screen::get() const {
  2. return _screen[_cursor];
  3. }

若将成员成员函数声明为const,则该函数不允许修改类的数据成员。例如,

[cpp] view plain copy

 

  1. class Screen {
  2. public:
  3. int ok() const {return _cursor; }
  4. int error(intival) const { _cursor = ival; }
  5. };

在上面成员函数的定义中,ok()的定义是合法的,error()的定义则非法。

值得注意的是,把一个成员函数声明为const可以保证这个成员函数不修改数据成员,但是,如果据成员是指针,则const成员函数并不能保证不修改指针指向的对象,编译器不会把这种修改检测为错误。例如,

[cpp] view plain copy

 

  1. class Name {
  2. public:
  3. void setName(const string &s) const;
  4. private:
  5. char *m_sName;
  6. };
  7. void setName(const string &s) const {
  8. m_sName = s.c_str();      // 错误!不能修改m_sName;
  9. for (int i = 0; i < s.size(); ++i)
  10. m_sName[i] = s[i];    // 不好的风格,但不是错误的
  11. }

虽然m_Name不能被修改,但m_sName是char *类型,const成员函数可以修改其所指向的字符。

const成员函数可以被具有相同参数列表的非const成员函数重载,例如,

[cpp] view plain copy

 

  1. class Screen {
  2. public:
  3. char get(int x,int y);
  4. char get(int x,int y) const;
  5. };

在这种情况下,类对象的常量性决定调用哪个函数。

[cpp] view plain copy

 

  1. const Screen cs;
  2. Screen cc2;
  3. char ch = cs.get(0, 0);  // 调用const成员函数
  4. ch = cs2.get(0, 0);     // 调用非const成员函数

小结:

1)const成员函数可以访问非const对象的非const数据成员、const数据成员,也可以访问const对象内的所有数据成员;

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

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

参考资料:

《C++ Primer第三版》

《Effective C++第三版》

C++的const类成员函数的更多相关文章

  1. 【转】C++的const类成员函数

    我们知道,在C++中,若一个变量声明为const类型,则试图修改该变量的值的操作都被视编译错误.例如, const char blank=' '; blank='\n'; //错误 面向对象程序设计中 ...

  2. [UE4]C++的const类成员函数

    我们知道,在C++中,若一个变量声明为const类型,则试图修改该变量的值的操作都被视编译错误.例如: const char blank = ‘’; blank = ‘\n’; // 错误 要声明一个 ...

  3. c++类成员函数后边加const是为什么?

    时间是让人猝不及防的东西,晴是有风阴时有雨,争不过朝夕,又念着往昔,偷走了青丝却留住一个你 #include <iostream> #include <string> usin ...

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

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

  5. 重载运算符:类成员函数or友元函数

    类成员函数: bool operator ==(const point &a)const { return x==a.x; } 友元函数: friend bool operator ==(co ...

  6. C++的类成员和类成员函数指针

    类成员函数指针: 用于访问类成员函数,和一般函数指针有区别. 类成员函数处理的是类数据成员,声明类成员函数指针的同时,还要指出具体是哪个类的函数指针才可以.调用时也要通过对象调用. 而对于类的静态成员 ...

  7. ### C++总结-[类成员函数]

    C++类中的常见函数. #@author: gr #@date: 2015-07-23 #@email: forgerui@gmail.com 一.constructor, copy construc ...

  8. 理解ATL中的一些汇编代码(通过Thunk技术来调用类成员函数)

    我们知道ATL(活动模板库)是一套很小巧高效的COM开发库,它本身的核心文件其实没几个,COM相关的(主要是atlbase.h, atlcom.h),另外还有一个窗口相关的(atlwin.h), 所以 ...

  9. C++ 空类默认产生的类成员函数

    C++的空类有哪些成员函数:. 缺省构造函数.. 缺省拷贝构造函数.. 缺省析构函数.. 缺省赋值运算符.. 缺省取址运算符.. 缺省取址运算符 const.     注意:有些书上只是简单的介绍了前 ...

随机推荐

  1. Google Now 'not available in your country'

    Google Now 'not available in your country' Don't know how to cope with this problem.

  2. make linux test main attempt to index a nil value

    Lua: getting started http://www.lua.org/start.html#learning Building from source Lua is very easy to ...

  3. pickle库的使用

    http://www.php.cn/python-tutorials-372984.html

  4. 持续交付的Mesos与Docker导入篇

    变革这个词在当今的数字化时代司空见惯,IT技术每过一段时间就会有一起革新,从WEB2.0.虚拟化.云计算.大数据.微架构.DevOps再到今天的容器Docker与Mesos. Docker的出现方便了 ...

  5. SQL和access随机数

    Access: CLng(Rnd(种子数字)*1000000)   SQL Server ceiling(rand(abs(checksum(newid())))*1000000)    

  6. linux IO多路复用POLL机制深入分析

    POLL机制的作用这里就不进行介绍,根据linux man手册,解释为在一个文件描述符上等待某个事件.按照抽象一点的理解,当某个事件被触发(条件被满足),文件描述符变为有状态,那么用户空间可以根据此进 ...

  7. 解决MySQL报错:1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column 'informat

    解决MySQL报错:1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column 'informat ...

  8. 002-线程实现方式【thread、runnable、callale、thread和runnable对比】

    一.概述 1.实现方式 在java中对于多线程实现一定要有一个线程的主类,而这个线程的主类往往是需要操作一些资源,但是对于多线程主类的实现是: 继承Thread父类 从java的Thread类继承实现 ...

  9. 常微分方程初值问题:单步方法 [MATLAB]

    #先上代码后补笔记# #可以直接复制粘贴调用的MATLAB函数代码!# 1. 朗格-库塔(Runge-Kutta)方法族 目前只实现了四阶Runge-Kutta方法. function [ YMat ...

  10. (15)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第三部分(完)

    引言 程序截图: 在第二部分教程中,Ray教大家如何在地图中制作可碰撞的区域,如何使用tile属性,如何制作可以拾取的物品以及如何动态修改地图.如何使用“Heads up display”来显示分数. ...