类的成员函数后面加 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. [转载]能不能同时用static和const修饰类的成员函数?

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

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

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

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

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

  4. 关于C++类的成员函数是否要加关键字“const”

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

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

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

  6. C++类的成员函数(在类外定义成员函数、inline成员函数)

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

  7. C++ - 模板类模板成员函数(member function template)隐式处理(implicit)变化

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

  8. VB6/VBA中跟踪鼠标移出窗体控件事件(类模块成员函数指针CHooker类应用)

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

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

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

随机推荐

  1. WinCE的开发流程

    总的来说,WinCE的开发是分为: 一.硬件开发:硬件设计,Boot Loader开发,OAL开发,BSP开发二.操作系统开发:定制驱动,创建最小内核,定制操作系统组件,测试集成三.应用程序开发:开发 ...

  2. 对比C++中的指针和引用

    指针和引用在形式上比较好区分,由于有很多相似的功能,因此在使用上容易混淆.因此有必要对指针和引用进行对比,以便于在使用时使程序正确高效. 1.引用不可以为空,而指针可以为空. 我们知道引用是对象的别名 ...

  3. BZOJ 3391 Tree Cutting网络破坏

    不想写. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> ...

  4. cocoStudio UI编辑器 学习总结

    一.控件 控件基类 UIWidget:所有UI控件的基类 addChild:添加UIWidget类型的节点 addRenderer:添加CCNode类型的节点 所有UIWidget,都可以设置成触摸s ...

  5. 常见SQLException异常

    ORA-00904:  invalid column name 无效列名 ORA-00942:  table or view does not exist 表或者视图不存在 ORA-01400:  c ...

  6. Spring无配置使用properties文件

    利用@PropertySource注解加载 @Configuration @ComponentScan(basePackages="*") @PropertySource({&qu ...

  7. 关于inline-block的间隙问题

    很久之前写过一个星星评级的样式,当时开发人员在嵌套代码的时候出现很多问题,同样的一个样式有的页面正常有的页面就出现星星错位的问题,仔细研究了一下代码,发现问题原来出在了inline-block上. 目 ...

  8. CSS hack——不同浏览器的CSS应对法

    1.IE条件注释法: lte表示“小于等于”,“lt”表示“小于”,“gte”表示“大于等于”,“gt”表示“大于”,“!”表示“不等于”. <!--[if IE 6]> <link ...

  9. myeclipse 8.5最新注册码(过期时间到2016年)

    myeclipse 8.5最新注册码(过期时间到2016年) 这几天myeclipse弹出注册码过期,去网上一搜,要么已过期,要么就剩一两个月.倒腾了半天,自己申请了几个注册码,给大家分享一下 Sub ...

  10. mysql中批量替换数据库中的内容的sql

    经过几次系统升级,遇到域名变了,文件存储目录变了,但之前被存到数据库里了,手动改太麻烦了,下面这个sql语句太给力了,屡试不爽. update table set body = replace(bod ...