目录
一、常对象——const对象 二、常成员函数——const成员函数
三、常数据成员——const数据成员
四、指向对象的常指针——指向对象的const指针
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
const修饰符,声明程序中的某些部件具有“常”的性质:只能用不能改变。
一、常对象——const对象 (常对象只能调用常成员函数)
凡希望保证数据成员不被改变的对象,可以声明为常对象,常对象中的所有成员的值都不能被修改。
常对象两种等价的定义形式:
类名 const 对象名[(实参表列)];
const 类名对象名[(实参表列)];
在定义常对象时,必须要在初始化时给出初值。
如:r1(2,2); 2和2就是给的初值
此外,对于常对象中数据成员的任何修改都是非法的,编译器将给出编译错误提示。
二、常成员函数——const成员函数(const对象只能调用常成员函数,而非const对象则都可以)
常对象引用数据成员时,需将该成员函数声明为const型函数,即常成员函数。//r2引用area()const 就可以,非const setY()就不行
常成员函数的原型为:
返回值类型成员函数名[(形参表列)] const;
注意,const是函数类型的一部分,在声明函数和定义函数时都要有const关键字,在调用时不必加const。
常对象在程序中调用的成员函数声明和实现时未加const,编译系统认为其是非const成员函数(会报错)。
常成员函数可以访问常对象中的数据成员,但不允许修改常对象中数据成员的值//r1调用constarea() 访问x 和y 返回他们的乘积
那么,在将一个对象定义为常对象时,是否意味着其所属类中的所有成员函数都应该为const成员函数呢?
不是这样的(只有他调用到的成员函数需要为const)。
例如下面的程序,常对象r1只能调用常成员函数area();
对象r3不是常对象,则可以调用非const函数setY();在其中还可以修改数据成员 y 的值,
也可以调用const 的area(),里面不允许有任何值的修改;。
提示:如果一个函数,如area(),无论何时都不会改变数据成员的值,不管将来是用于const对象,还是非const对象,都将其定义为const成员函数。
三、常数据成员——const数据成员
常对象是一个非常强的要求,其中的所有数据成员将不能改变。
而实际中的需求是这样的:一个对象中,个别数据成员的值经初始化后不允许改变,其他的可以改变。
这时,不要将对象设为常对象,而是使用常数据成员——const数据成员。
声明常数据成员也用关键字const,其形式为:
const 数据类型数据成员名;
const成员函数,它能够访问const数据成员,也能访问非const数据成员。
将area()声明为非const成员函数,取消了不能修改数据成员的限制,
同样对const数据成员和非const数据成员都能访问,不过此时若要修改,只能修改y,而不能修改x(const)。
延伸:
1)所有数据成员都需要修改。什么都不做,默认就好
2)所有数据成员都不需要修改。我们在定义对象时将对象定义为常对象处理
3)大量数据成员需要修改,只有少量不允许修改。将少量的定义为const数据成员。
4)大量数据不允许修改,只有少量允许修改。一定要修改常对象中的某个数据成员,该数据成员声明为mutable
四、指向对象的常指针——指向对象的const指针
如果在定义指向对象的指针时,使用了关键字Const,它就是一个常指针,必须在定义时对其初始化。
并且在程序运行中不能再修改指针的值。
格式如下:
类名 *const 指针变量名=对象地址
综合实例:
************************************************************
*版权所有 (C)
* 文件名称: 常对象和常成员函数
* 文件标识: 无
* 内容摘要: 通过计算长方形的面积来展示const对象和const成员函数和const数据成员const对象指针和指向对象的const指针的特性
* 当前版本: 1.0
* 作 者: 陈涛
* 完成日期: 2015-07
*
***************************************************************/
#include "stdafx.h"
#include <iostream>
using namespace std;
class Rectangle
{
public:
Rectangle (int m=0, int n=0) :x(m) //此处x必须这么初始化,而y是相当于赋值。(y比x多一步),y也最好采用和x一样 的初始化
{
this->y = n;
}
//void setX(int x); //修改const数据成员是不允许的
void setY(int y);
int area() const ; //函数中运行过程中一定不会修改数据成员的值,定义为const成员函数
private:
const int x; //常数据成员
int y;
};
void Rectangle::setY(int y)
{
this->y = y;
}
int Rectangle::area() const
{
return x*y;
}
int main()
{
Rectangle const r1(2, 2);
//r1.setY(5); //"常"对象不能调用非"常"成员函数
cout << r1.area() << endl; //"常"对象能调用"常"成员函数
const Rectangle r2(4, 4); //r1和r2都是"常"对象
Rectangle r3(5, 5);
//r3.steX(4); //因为x为const 不能修改,此处错误
r3.setY(4); //非 "常"对象可以调用非"常"成员函数
cout << r3.area() << endl; //非 "常"对象也可以调用"常"成员函数
Rectangle r4(); <span style="white-space:pre"> </span>//r3和r4都是非"常"对象 ,可以赋初值也可以不赋初值
Rectangle const* p1; <span style="white-space:pre"> </span>//定义了一个指向"常"Rectangle对象的指针。 此指针只能指向"常"对象,
<span style="white-space:pre"> </span>//可以指向不同的"常"对象 现在指向r1,下面又可以指向r2
p1 = &r1;
p1 = &r2; //
Rectangle* const p2 = &r3; //定义了一个"常"指针,只能指向非"常"对象,必须在定义时就给他进行初始化。
//p2 = &r4; //而且指向了一个对象后就始终指向这个对象,不能再指向其他对象了,又想指向r4,
<span style="white-space:pre"> </span>//因为是常指针,只能始终指向上面的r3,所以报错
return 0;
}