常变量
指向常量的指针变量
常指针
指向常量的常指针
常对象
常数据成员
常成员函数
指向常对象的指针变量
指向对象的常指针
对象的常引用
常变量:在定义变量时加上关键字const,则变量的值在程序运行期间不能改变,这种变量称为常变量(又称为只读变量)。在定义常变量时必须同时对它进行初始化,此后它的值不能再改变。应该注意的是区别#define指令定义的符号常量和const定义的常变量。符号常量是用一个符号代替一个字符串,在预编译时把所有符号常量替换程所指定的字符串,它没有类型,在内存中不存在以符号常量命名的存储单元。而常变量具有变量的特性,它具有类型,在内存中存在这以它名字命名的存储单元,可以用sizeof运算符测出其长度。
可以指定指针变量是一个常量,或者指定指针变量指向的对象是一个常量,有以下几种情况:
a)指向常量的指针变量
定义:const 类型名 × 指针变量名
此定义表示被指物是常量(底层const),const关键字和类型名交换位置表示同样的意思。经此定义后,不允许通过指针变量改变它所指向的对象的值(允许不通过指针来改变变量的值,如直接赋值,这一点也区别常变量,若想无论以何种方式都不能改变变量的值,则将变量声明为常变量),但是可以改变指针变量的值。指向常量的指针变量常用于作函数形参,以防止指针形参所指对象的值改变影响实参。
b)常指针:
定义:类型名 ×const 指针变量名
指定指针变量的值是常量,即指针变量的指向是不能改变的。常指针必须在定义时进行初始化,指定其指向。要注意的是,指针值是不能改变的,但是指针变量的指向变量是可以改变的。
c)指向常量的常指针:
定义:const 基本类型名 ×const 指针变量名
把以上两种作用叠加在一起,就是指向常量的指针变量,即指针变量指向一个固定的对象,该对象的值不能通过改变指针变量改变该对象的值。
常对象:在定义对象时加上关键字const指定对象为常对象,常对象必须有初值。凡希望保证数据成员不被改变的对象,可以声明为常对象。
定义:类名 const 对象名 [(实参表)] 或者 const 类名 对象名 [(实参表)] (二者等价)
不能调用常对象中的普通成员函数和常成员函数不能修改对象的数据成员这两点保证了常对象中的数据成员的值绝不会被改变。
- 定义常对象时,必须同时对它进行初始化,之后其数据成员不能再更改(常对象保证其数据成员是常数据成员(默认为常数据成员,无需额外声明),其值不能被修改,但是不保证成员函数都为常成员函数(要声明需要加const))
- 如果一个对象被声明为常对象,则通过该对象只能调用它的常成员函数,而不能调用该对象的普通成员函数(除了系统自动调用的隐式的构造函数和析构函数)。常成员函数是常对象唯一的对外接口。
- 要引用常对象的数据成员,需要将该成员函数声明为const即可(常成员函数可以引用常对象中的(常)数据成员)。常成员函数可以访问常对象中的数据成员,但是仍然不允许修改常对象中的数据成员。
- 编程中若一定要修改常对象中的某个数据成员,可以将该数据成员声明为mutable
mutable int a; //声明为可变数据成员,可以用声明为const的成员函数来修改。
常对象中的数据成员有两种,默认为常数据成员,声明为mutable成员,成员函数也有两种,普通成员函数(通过对象不可调用,要来何用???),声明为const成员函数。
常数据成员:可以将对象中的数据成员声明为const。常对象中的数据成员默认为const类型。常数据成员的作用和用法和一般常变量相似。需要注意的是:只能通过构造函数的参数初始化表对常数据成员进行初始化,任何其他函数都不能对常数据成员赋值。
常成员函数:如果将成员函数声明为常成员函数,则只能引用本类中的数据成员,而不能修改它们。
定义:类型名 函数名 (参数表) const
const是函数类型的一部分,在声明函数和定义时都要有关键字const关键字,在调用时就不用了。
数据成员 | 非const普通成员函数 | const成员函数 |
非const的普通数据成员 | 可以引用,可以改变其值 | 可以引用,不能改变其值 |
const数据成员 | 可以引用,不能改变其值 | 可以引用,不能改变其值 |
const对象 | 不允许 | 可以引用,不能改变其值 |
注:常成员函数不能调用另一非const成员函数。
指向常对象的指针变量
指向常变量的指针变量 | 指向常对象的指针变量 |
const 类型名 × 指针变量名 | const 类名 × 指针变量名 |
常变量只能用指向常变量的指针变量来指向它,不能用一般的指针变量 | 常对象只能用指向常对象的指针变量来指向它,而不能用一般的指针变量 |
指向常变量的指针可以指向常变量和普通变量,此时不能通过指针变量来改变该变量的值 | 指向常对象的指针变量用来指向非const对象,则其指向的对象是不能通过该指针变量来改变 |
| 指向常对象的指针最常用作函数形参,目的是保护形参指针所指向的对象,使它在函数执行期间不被修改。 |
注:
如果定义了指向常变量的指针变量p,并使它指向c1,并不意味着把c1也声明为常变量,而只是在用指针变量访问c1期间,c1具有常变量的特征,其值不能改变。在其他情况下,c1仍然是一个普通的变量,其值是可以修改的。
指向对象的常指针
将指针变量声明为const型,这样指针变量始终保存为初值,不能改变,即其指向不变。
定义:
类名 × const 指针变量名
指向对象的常指针变量的值不能改变,即始终指向同一个对象,但是可以改变其所指对象的值。往往用作函数的形参,目的是不允许在函数执行期间改变指针变量的值,使其始终指向原来的对象。
注:记住一条规则
当希望在调用函数时对象的值不能被改变,就应该把形参定义为指向常对象的指针变量,同时用对象的地址做实参(&t1)(对象可以是const或者非const)。如果要求该对象不仅在调用函数过程中不被改变,而且要求它在程序执行过程中都不改变,则应把它定义为const型。
用指针变量做形参时形参和实参的对应关系
形参 | 实参 | 合法否 | 改变指针所指向的变量的值 |
指向非const型变量的指针 | 非const变量的地址 | 合法 | 可以 |
指向非const型变量的指针 | const变量的地址 | 不合法 | / |
指向const型变量的指针 | const变量的地址 | 合法 | 不可以 |
指向const型变量的指针 | 非const变量的地址 | 合法 | 不可以 |
对象的常引用:一个变量的引用就是变量的别名,实际上,引用是一个指针常量,用来存放该变量的地址。如果形参为变量的引用,实参为变量名,则在函数进行虚实结合时,把实参变量的地址传给形参(引用),这样就引出指向实参变量。对象的引用与此类似,也可以把引用声明为const,及常引用。
常引用做函数形参,在函数中不能改变形参所代表的实参的值,注意,不是不能改变形参的“指向”,而是形参所指向的变量的值。(指向常变量的指针?)
在C++面向对象的编程中,经常用常指针和常引用做函数参数,这样技能保证数据安全,使数据不能被随意修改,在调用函数时又不必建立实参的拷贝。
形式 | 含义 |
Time const t; | t是常对象,其值在任何情况下都不能被修改 |
void Time::fun() const | fun是Time类中的常成员函数,可以引用,但不能修改本类中数据成员 |
Time *const p; | p是指向Time类对象的常指针变量,p的值(p的指向)不能改变 |
const Time *P | p是指向Time类常对象的指针变量,p指向的类对象的值不能通过p改变 |
const Time &t1=t | t1是Time类对象的t的引用,二者指向同一存储空间,t的值不能被改变 |