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

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

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

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

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

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

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

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

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

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

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

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

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

  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成员函数重载,例如,

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

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

  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. const成员函数

    尽管函数名和参数列表都相同,void foo( ) const成员函数是可以与void foo( )并存的,可以形成重载! 我们假设调用语句为obj.foo(),如果obj为non-const对象,则 ...

  2. c++ 学习之const专题之const成员函数

    一些成员函数改变对象,一些成员函数不改变对象. 例如: int Point::GetY() { return yVal; } 这个函数被调用时,不改变Point对象,而下面的函数改变Point对象: ...

  3. 关于 const 成员函数

    成员函数如果是const意味着什么? 有两个流行概念:物理常量性和逻辑常量性. C++对常量性的定义采用的是物理常量性概念,即const 成员函数不可以更改对象内任何non-static成员变量.例如 ...

  4. C++ Const成员函数

    一些成员函数改变对象,一些成员函数不改变对象. 例如:  int Point::GetY() { return yVal; }  这个函数被调用时,不改变Point对象,而下面的函数改变Point对象 ...

  5. C++类的const成员函数、默认的构造函数、复制形参调用函数(转)

    C++类的const成员函数 double Sales_item::avg_price() const { } const关键字表明这是一个const成员函数,它不可以修改Sales_item类的成员 ...

  6. c++中的const参数,const变量,const指针,const对象,以及const成员函数

    const 是constant 的缩写,“恒定不变”的意思.被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性.所以很多C++程序设计书籍建议:“Use const whe ...

  7. 拷贝构造函数和const成员函数

    实验原因 说明如何使用const描述保护类数据不会意外修改. 编译环境 vc6sp6 + win7x64 工程下载 copyConstruction_constMemberFunction.zip   ...

  8. 12.C++-构造函数与析构函数调用顺序,const成员函数,const对象

    单个对象创建时,构造函数的调用顺序 1.首先判断该对象的类是否拥有父类,若有则先调用父类的构造函数 2.判断该对象的成员是否是其它类的成员,若是则调用成员变量的构造函数(调用顺序和声明顺序相同) 3. ...

  9. const 成员函数

    我们知道,在成员函数中,如果没有修改成员变量,应该给成员函数加上 const 修饰符,例如 #include <iostream> using namespace std; class F ...

  10. Item 16: 让const成员函数做到线程安全

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 如果我们在数学领域里工作,我们可能会发现用一个类来表示多项式会很方 ...

随机推荐

  1. Git 常用命令总结,掌握这些,轻松驾驭版本管理

    原创 最近公司的代码管理工具要从SVN转到Git上,因此虽然之前用过Git,但是都是一些简单的推送提交,因此还是有必要进行一些系统的学习,这里做一下笔记,以备后询,且不定期更新. 关于SVN和Git的 ...

  2. VIM - 问题: 简单变换

    1. 概述 学习 Java 反射的时候, 碰到的简单问题 手动可以处理, 但是真的很浪费时间 想熟悉一下工具的使用 2. 题目 源 Modifier.isAbstract(int modifiers) ...

  3. 每天进步一点点------SOPC的Avalon-MM IP核(一) avalon总线的信号时序

    在SOPC中自定义外设时.可以设置avalon总线的信号时序,以满足外设的要求.一般情况下,可以设为: 其中setup为read和write信号之前,address和writedata信号提前建立的时 ...

  4. 【Webpack】

    目录 关于模块化编程 Webpack的工作方式 三个重要的概念 使用Webpack创建一个项目 正式使用Webpack 使用Webpack进行ES6的模块化编程 "本质上,Webpack是一 ...

  5. JavaScript自学笔记(1)---表单验证,let和const,JSON文件

    今天开个JS自学笔记,本身JS的语法很简单,如果学过Java或者C系的都很容易,就不讨论了.主要是讨论实际应用的问题. 1.表单验证: a.html自动验证: HTML 表单验证可以通过浏览器来自动完 ...

  6. 一份比较详细的DOS命令说明

    一份比较详细的DOS命令说明 1 echo 和 @ 回显命令 @                     #关闭单行回显 echo off              #从下一行开始关闭回显 @echo ...

  7. java篇 之 数组

    数组:本身也是对象元素数据类型必须一致,初始值为各种零(跟类型一致),数组中存放 的是对象的引用(地址),对象在其它空间,一旦创建长度不可变,length可以直 接访问 (new的时候才分配空间,创建 ...

  8. tensorflow 学习记录

    函数变动 tf.train.SummaryWriter 变为 tf.summary.Filewritter 函数功能相同,仅仅是简单的重命名 ``` writer = tf.summary.FileW ...

  9. ubuntu16.04/ubuntu18.04安装网易云音乐

    一.下载1.0版本 下载地址:http://s1.music.126.net/download/pc/netease-cloud-music_1.0.0_amd64_ubuntu16.04.deb 下 ...

  10. Leader:这样的 Bug 你也写的出来???

    Hello~各位读者新年好!不知道大家春节假期是否已延长,小黑哥刚接到通知,假期延长到 2 月 2 号,另外回去之后需要在家办公,自行隔离两周.还没试过在家办公,小黑哥就怕到时候生物钟还没调整过来,一 ...