(根据《C++程序设计》(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明)

C++为什么要引入const?它允许你指定一个语义约束(也就是指定一个“不该被改动”的对象),而编译器会强制实施这项约束。它允许你告诉编译器和其他程序员某值应该保持不变。只要这是事实,你就该确实说出来,因为说出来可以获得编译器的襄助,确保这条约束不被违反。另外,C++虽然采取了不少有效的措施(如设private保护)以增加数据的安全性,但是有些数据往往是共享的,例如实参与形参,变量与其引用,数据及其指针等,人们可以在不同的场合通过不同的途径访问同一个数据对象。有时在无意之中的操作会改变有关数据的状况,而这是人们不希望出现的。既要使数据能在一定范围内共享,又要保证它不被任意修改,这时可以把有关的数据定义为常量。

1. 修饰指针

可以指定指针变量是一个常量,或者指针变量指向的对象是一个常量。有下面几种情况:

1.1 指向常量的指针变量

一般形式:const 类型名* 指针变量名,不允许通过指针变量改变它指向的对象的值。例如:

   1: int a = 12 , b = 15 ;

   2: const int* p = &a ;

   3: *p = 15 ; // 试图通过p改变它指向的对象的值,非法

不能通过指针来改变所指对象的值,但是直接改变对象的值是合法的:

   1: a = 15 ;

另外,指针变量的值是可以改变的:

   1: p = &b ;

用指向常量的指针变量只是限制了通过指针改变它指向的对象的值 。如果要想绝对保证对象的值始终不变,应当把它定义为常变量:

   1: const int a = 15 ;

   2: const int* p = &a ; /*此时,指针必须为const int * ,因为&a的类型就是const int * ,否则会出错。*/

无论用直接访问方式或间接访问方式都无法改变对象的值。
    指向常量的指针变量常用于作函数形参,以防止指针形参所指对象的值改变影响实参。

1.2 常指针变量

一般形式:类型名* const 指针变量名, 指定指针变量的值是常量,即指针变量的指向不能改变。常指针变量简称常指针,必须在定义时初始化,指定其指向;指针变量的指向不能改变,但其指向变量的值是可以改变的:

   1: int a = 4 ;

   2: int b = 6 ;

   3: int* const p = &a ;

   4: p = &b ; /*试图改变p的指向,不合法*/

   5: *p = 12 ;/*改变p的指向变量的值,合法*/

1.3 指向常量的常指针

一般形式:const 基本类型名* const 指针变量名,把以上两种作用叠加一起,就是指向常量的常指针变量。指针的指向不可改变,其指向变量的值也不可以通过指针改变。

3. class中应用

为了说明问题,先构造一个类:

   1: class Time

   2: {

   3: public:

   4:     int hour ;

   5:     int minute ;

   6:     int sec ;

   7:     void get_time();

   8: };

   9: void Time::get_time()

  10: {

  11:     cout << hour << ":" << minute << ":" << sec << endl ;

  12: }

3.1 常对象

一般形式:类名 const 对象名[(实参表)]  或 const 类名 对象名[(实参表)] ,在定义常对象时,必须同时对之初始化,之后不能再改变。在对象的周期内,其所有的数据成员的值都不能被修改。

   1: Time const t1(12,34,46) ;/*定义t1是常对象*/

说明:

(1)如果一个对象被声明为常对象,则通过该对象只能调用它的常成员函数,而不能调用该对象的普通成员函数。

   1: const Time t1(10,15,36);

   2: t1.get_time();/*试图调用常对象的普通成员函数,非法!*/

(2)常成员函数可以访问常对象中的数据成员,但仍然不允许修改常对象中的数据成员。

3.2 常数据成员

常数据成员的值是不能改变的。注意:只能通过构造函数的参数初始化表对常数据成员进行初始化,任何其他函数都不能对常数据成员赋值,即使在构造函数中也不行。

   1: const int hour ;//定义hour为常数据成员

   2: Time::Time(int h)

   3: {

   4:     hour = h ;  //非法,不能在构造函数中对常数据成员初始化

   5: }

   6:  

   7: Time::Time(int h):hour(h)

   8: { }  //合法,通过参数初始化表的方式初始化常数据成员

   9:  

由于常对象的数据成员都是常数据成员,因此在定义对象时,构造函数只能采用参数初始化表对常数据成员进行初始化。

3.3 常成员函数

一般形式:类型名 函数名(参数表)const,const是函数类型的一部分,在声明和定义时都要有const,调用时不必。

前面提到:一般的成员函数可以引用本类中的非const数据成员,也可以修改它们。如果将成员函数声明为常成员函数,则只能引用本类中的数据,而不能修改它们。

有个重要的表格:

数据成员 非const成员函数 const成员函数
非const数据成员 引用+修改 引用,不可修改
const数据成员 引用,不可修改 引用,不可修改
const对象 不允许 引用,不可修改

如何利用常成员函数?:

(1)如果在一个类中,有些数据成员的值允许改变,有些不允许。则可以将不允许改变的声明为const,以保证其值不被改变,可以用非const成员函数引用这些数据成员的值,并修改非const数据成员的值。

(2)如果要求所有的数据成员都不允许改变,则可以将所有的数据成员声明为const或将对象声明为const(常对象),然后const成员函数引用数据成员。

(3)如果已经定义了一个常对象,只能调用其中的const成员函数。

C++学习之路—const用法总结的更多相关文章

  1. OpenGL学习之路(一)

    1 引子 虽然是计算机科班出身,但从小对几何方面的东西就不太感冒,空间想象能力也较差,所以从本科到研究生,基本没接触过<计算机图形学>.为什么说基本没学过呢?因为好奇(尤其是惊叹于三维游戏 ...

  2. java学习之路之javaSE基础1

    <h2>java学习之路之javaSE基础1</h2> <div> ###01.01_计算机基础知识(计算机概述)(了解)* A:什么是计算机?计算机在生活中的应用 ...

  3. Qt 学习之路 2(63):使用 QJson 处理 JSON

    Home / Qt 学习之路 2 / Qt 学习之路 2(63):使用 QJson 处理 JSON Qt 学习之路 2(63):使用 QJson 处理 JSON  豆子  2013年9月9日  Qt ...

  4. Qt 学习之路 2(16):深入 Qt5 信号槽新语法

    Qt 学习之路 2(16):深入 Qt5 信号槽新语法  豆子  2012年9月19日  Qt 学习之路 2  53条评论 在前面的章节(信号槽和自定义信号槽)中,我们详细介绍了有关 Qt 5 的信号 ...

  5. vue学习之路 - 4.基本操作(下)

    vue学习之路 - 4.基本操作(下) 简述:本章节主要介绍 vue 的一些其他常用指令. Vue 指令 这里将 vue 的指令分为系统内部指令(vue 自带指令)和用户自定义指令两种. 系统内部指令 ...

  6. ReactNative新手学习之路07ListView_ renderHeader使用StaticContainer

    react native新手学习之路07ListView_ renderHeader使用StaticContainer 1.某些特殊场景需要用ScrollView滚动和ListView配合但是不幸运的 ...

  7. OpenGL学习之路(四)

    1 引子 上次读书笔记主要是学习了应用三维坐标变换矩阵对二维的图形进行变换,并附带介绍了GLSL语言的编译.链接相关的知识,之后介绍了GLSL中变量的修饰符,着重介绍了uniform修饰符,来向着色器 ...

  8. OpenGL学习之路(五)

    1 引子 不知不觉我们已经进入到读书笔记(五)了,我们先对前四次读书笔记做一个总结.前四次读书笔记主要是学习了如何使用OpenGL来绘制几何图形(包括二维几何体和三维几何体),并学习了平移.旋转.缩放 ...

  9. 12天学好C语言——记录我的C语言学习之路(Day 10)

    12天学好C语言--记录我的C语言学习之路 Day 10: 接着昨天的指针部分学习,有这么一个题目: //还是四个学生,四门成绩,只要有学生一门功课没及格就输出这个学生的所有成绩 /*//progra ...

随机推荐

  1. c++,public/protected/private权限修饰符

    1.public的变量可以在类中以及外部访问到: 2. private只可以在类/友元中访问到. #include <iostream> using namespace std; //-- ...

  2. QGraphicsView中选中QGraphicsPathItem使之不出现虚线框

    绘制一条贝赛尔曲线,当选中该曲线时,显示其控制点并把控制点和起始点连结起来,从而可以清晰的显示曲线的参数. # -*- coding: utf-8 -*-from PyQt4 import QtGui ...

  3. 使用zabbix监控nginx

    在zabbix agentd客户端上,查看nginx是否加载了--with-http_stub_status_module.因为zabbix监控nginx是根据 nginx的Stub Status模块 ...

  4. Python 2.7 学习笔记 访问mysql数据库

    一.基本概念 使用python操作数据库,其基本的流程如下(其实所有开发语言访问数据库的流程都是这样). 1.第一,引入相应数据库的python数据库接口模块,针对不同的数据库类型,有不同的数据库访问 ...

  5. PHP $_SERVER['PHP_SELF']、$_SERVER['SCRIPT_NAME'] 与 $_SERVER['REQUEST_URI'] 之间的区别

    PHP $_SERVER['PHP_SELF'].$_SERVER['SCRIPT_NAME'] 与 $_SERVER['REQUEST_URI'] $_SERVER['PHP_SELF'].$_SE ...

  6. javascript语言精粹:继承

    继承提供了2个有用的任务: 1.代码重用 2.引入了一套类型系统的规范,因为程序员无需编写显示类型转换的代码,他们的工作量将大大减轻.这是一件很好的事情,应为类型转换会丧失类型系统在安全上的优势. 在 ...

  7. 修复ubuntu播放wmv等视频没有声音问题

    1. Mplayer or SMplayer 1.1 原因: 很可能是你没有安装 w32codes 1.2 解决方法: (1)下载 w32codes 官方站点 all-20110131.tar.bz2 ...

  8. ACM第三次比赛 Big Chocolate

    Problem G Big Chocolate Mohammad has recently visited Switzerland . As he loves his friends very muc ...

  9. 国产CPU走到十字路口:谁来取代英特尔芯片?(少写了一个OpenPower)

    国内的几支CPU研发力量各自选择的指令体系都有自己的优点和问题,选择其中的哪一支都会有对应的成本和风险.最终谁能担大任,且拭目以待. 文 | 瞭望智库特约科技观察员 王强 用上内置国产CPU的个人电脑 ...

  10. poj 2891 Strange Way to Express Integers(中国剩余定理)

    http://poj.org/problem?id=2891 题意:求解一个数x使得 x%8 = 7,x%11 = 9; 若x存在,输出最小整数解.否则输出-1: ps: 思路:这不是简单的中国剩余定 ...