用 const 限定类的成员函数

时间:2023-02-16 15:02:49

类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变。

在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 const,而对于改变数据成员的成员函数不能加 const。所以
const 关键字对成员函数的行为作了更加明确的限定:有 const 修饰的成员函数(指 const
放在函数参数表的后面,而不是在函数前面或者参数表内),只能读取数据成员,不能改变数据成员;没有 const
修饰的成员函数,对数据成员则是可读可写的。

除此之外,在类的成员函数后面加 const 还有什么好处呢?那就是常量(即 const)对象可以调用 const 成员函数,而不能调用非const修饰的函数。正如非const类型的数据可以给const类型的变量赋值一样,反之则不成立。

请看下面一个完整的例子,然后我再作一些说明。

#include <iostream>
#include <string>
using namespace std;

class Student {
public:
  Student() {}
  Student( const string& nm, int sc = 0 )
    : name( nm ), score( sc ) {}

void set_student( const string& nm, int sc = 0 )
  {
    name = nm;
    score = sc;
  }

const string& get_name() const
  {
    return name;
  }

int get_score() const
  {
    return score;
  }

private:
  string name;
  int score;
};

// output student's name and score
void output_student( const Student& student )
{
  cout << student.get_name() << "/t";
  cout << student.get_score() << endl;
}

int main()
{
  Student stu( "Wang", 85 );
  output_student( stu );
}

设 计了一个类 Student,数据成员有 name 和 score,有两个构造函数,有一个设置成员数据函数
set_student(),各有一个取得 name 和 score 的函数 get_name() 和 get_score()。请注意
get_name() 和 get_score() 后面都加了 const,而 set_student() 后面没有(也不能有const)。

首先说一点题外话,为什么 get_name() 前面也加 const。如果没有前后两个 const 的话,get_name() 返回的是对私有数据成员 name 的引用,所以通过这个引用可以改变私有成员 name 的值,如

  Student stu( "Wang", 85 );
  stu.get_name() = "Li";

即把 name 由原来的 "Wang" 变成了 "Li",而这不是我们希望的发生的。所以在 get_name() 前面加 const 避免这种情况的发生。

那么,get_name() 和 get_score() 这两个后面应该加 const的成员函数,如果没有 const 修饰的话可不可以呢?回答是可以!但是这样做的代价是:const对象将不能再调用这两个非const成员函数了。如

const string& get_name(); // 这两个函数都应该设成 const 型
int get_score();
void output_student( const Student& student )
{
  cout << student.get_name() << "/t"; // 如果 get_name() 和 get_score() 是非const成员函数,这一句和下一句调用是错误的
  cout << student.get_score() << endl;
}

由 于参数student表示的是一个对const Student型对象的引用,所以 student 不能调用非const成员函数如
set_student()。如果 get_name() 和 get_score() 成员函数也变成非const型,那么上面的
student.get_name() 和 student.get_score() 的使用就是非法的,这样就会给我们处理问题造成困难。

因此,我们没有理由反对使用const,该加const时就应该加上const,这样使成员函数除了非const的对象之外,const对象也能够调用它。

用 const 限定类的成员函数的更多相关文章

  1. &lbrack;转载&rsqb;能不能同时用static和const修饰类的成员函数?

    题目(一):我们可以用static修饰一个类的成员函数,也可以用const修饰类的成员函数(写在函数的最后表示不能修改成员变量,不是指写在前面表示返回值为常量).请问:能不能同时用static和con ...

  2. &period;static 和const分别怎么用,类里面static和const可以同时修饰成员函数吗。

    static的作用: 对变量: 1.局部变量: 在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量. 1)内存中的位置:静态存储区 2)初始化:局部的静态变量只能被初始化一次, ...

  3. C&plus;&plus;类的成员函数的形参列表后面的const

    看到(C++ Primer)类的成员函数这里,突然对成员函数形参列表后面的const感到迷惑. 因为书中开始说是修饰隐含形参this的,然后又说是声明该函数是只读的. 大为不解! 翻资料.找人讨论.. ...

  4. 关于C&plus;&plus;类的成员函数是否要加关键字&OpenCurlyDoubleQuote;const”

    原则:类的成员函数在小括号后大括号前加上 const ,代表不准备改变对象的数据.不加的话代表有可能会改变对象的数据. 1.当常量对象,就是加上const修饰的类的成员去调用常量成员函数时,这表示:对 ...

  5. VC版本的MakeObjectInstance把WNDPROC映射到类的成员函数

    这段时间用VC封装Windows类库,没有MakeObjectInstance处理窗口消息确实不爽,又不想使用MFC的消息映射,这玩意的效率和美观只能呵呵. 至于MakeObjectInstance是 ...

  6. C&plus;&plus;类的成员函数&lpar;在类外定义成员函数、inline成员函数&rpar;

    类的成员函数(简称类函数)是函数的一种,它的用法和作用和前面介绍过的函数基本上是一样的,它也有返回值和函数类型,它与一般函数的区别只是:它是属于一个类的成员,出现在类体中.它可以被指定为private ...

  7. C&plus;&plus; - 模板类模板成员函数&lpar;member function template&rpar;隐式处理&lpar;implicit&rpar;变化

    模板类模板成员函数(member function template)隐式处理(implicit)变化 本文地址: http://blog.csdn.net/caroline_wendy/articl ...

  8. VB6&sol;VBA中跟踪鼠标移出窗体控件事件&lpar;类模块成员函数指针CHooker类应用&rpar;

    一.关于起因 前几天发了一篇博文,是关于获取VB类模块成员函数指针的内容(http://www.cnblogs.com/alexywt/p/5880993.html):今天我就发一下我的应用实例. V ...

  9. C&plus;&plus;编译器是如何管理类和对象的,类的成员函数和成员变量

    C++中的class从面向对象理论出发,将变量(属性)和函数(方法)集中定义在一起,用于描述现实世界中的类.从计算机的角度,程序依然由数据段(栈区内存)和代码段(代码区内存)构成. #include ...

随机推荐

  1. Zookeeper核心机制

    (如果感觉有帮助,请帮忙点推荐,添加关注,谢谢!你的支持是我不断更新文章的动力.本博客会逐步推出一系列的关于大型网站架构.分布式应用.设计模式.架构模式等方面的系列文章) Zookeeper是Hado ...

  2. 推荐 15 个 Angular&period;js 应用扩展指令&lpar;参考应用&rpar;

    几天前我们看到Angular 1.4.0发布了-一个以社团为驱动的发布版本涵盖了400多个GitHub的提交,增加了对特性的提升,比如动画,以及可用性. 官方新闻发布稿 覆盖了绝大部分,这同样值得放于 ...

  3. noip普及组2007 Hanoi双塔问题

    Hanoi双塔问题 描述 给定A,B,C三根足够长的细柱,在A柱上放有2n个中间有孔的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的.现要将这些圆盘移到C柱上,在移动 ...

  4. LOJ&period;2864&period;&lbrack;IOI2018&rsqb;排座位&lpar;线段树&rpar;

    LOJ 洛谷 先令编号从\(1\)开始.我们要求\([1,i]\)这些数字能否构成一个矩形. 考虑能否用线段树维护,让每个叶子节点\(i\)表示前\(i\)个数能否构成矩形. 一种方法是维护前\(i\ ...

  5. Android学习笔记二之初始Activity

    初识Activity,跟着教程学习敲了一遍这一章的内容,下面根据目录结构总结知识点: 一.活动是什么 上篇博文中我们提到了Android四大组件,其中有一个Activity,我们将之称为活动.活动是最 ...

  6. 微信小程序设置背景铺满全屏

    参考方法: 新版本升级取消了默认page的100%的特性 需要在app.wxss文件中加入如下代码: page{ height:100%; }

  7. SQL Server2008 18456错误

    1.以windows验证模式进入数据库管理器.   第二步:右击sa,选择属性:   在常规选项卡中,重新填写密码和确认密码(改成个好记的).把强制实施密码策略去掉.   第三步:点击状态选项卡:勾选 ...

  8. Java调用使用SSL&sol;HTTPS协议来传输的axis webservice服务

    使用SSL/HTTPS协议来传输 Web服务也可以使用SSL作为传输协议.虽然JAX-RPC并没有强制规定是否使用SSL协议,但在tomcat 下使用HTTPS协议. 1.使用JDK自带的工具创建密匙 ...

  9. Linux&&num;160&semi;CentOS&&num;160&semi;6&period;5&&num;160&semi;下&&num;160&semi;vsftpd&&num;160&semi;ftp服务器搭建

    Linux CentOS 6.5 下 vsftpd ftp服务器搭建 by:授客 QQ:1033553122   操作系统环境:CentOS 6.5-x86_64 下载地址:http://www.ce ...

  10. 使用Jmeter对API进行性能测试

    先补充刚才测试的部分截图余下,后续详细补充内容. API Test.jmx 如下: <?xml version="1.0" encoding="UTF-8&quot ...