const限定
(1)限定一个对象
C语言使用预处理指令#define定义符号常量,但是这种常量的缺点在于它只是进行简单的字符串替换,
不进行类型检查。const限定将一个对象限定为常量。例如:
const int bufSize = 1024;
定义bufSize为一个常量,初始化为1024,企图修改这个值会导致编译错误。因为常量的值不能修改,
所以必须在定义时初始化。
(2)限定指针
限定指针有两种,例如:
int ival = 1024;
const int* pi = & ival; //第一种
int* const pi2 = & ival; //第二种
(注意:const指针必须初始化)
第一种const是限定int,表示指针pi指向内存单元的值(*pi)是常量,不能改变。
第二种const是限定int*,表示指针pi的值是一个常量,不能改变。
所以有:
*pi = 1000; //error,pi指向内存单元的值不能改变。
int ival2 = 1000;
pi2 = &ival2; //error,指针pi一旦指定就不能改变。
#1.const地址不能赋值给非const指针
#2.非const地址和const地址都能赋值给const指针
int ival = 1024;
const int ival2 = 1000;
const int* pi = &ival; //ok,将int*类型的地址赋值给const int*类型指针
pi = &ival2; //ok,将const int*类型的地址赋值给const int*类型指针
*pi = 2000; //error, 指针指向内存单元的值不能修改
int* const pi2 = &ival; //ok,将int*类型的地址赋值给int* const类型的指针
*pi2 = 1000; //ok, 对于*pi没有限定,且内存单元值没有const限定,可以修改
pi2 = &ival2; //error,const限定int*,指针pi2的值不能改变
(3).const限定函数参数和函数返回值
对按值传递的函数参数和函数返回值, const限定没有任何意义,
而对于引用和指针传递的函数参数或函数返回值,可以使用const限定。
例如:
const string& longerString(const string &sa, const string &sb)
{
return sa.size() > sb.size() ? sa : sb;
}
(4)const数据成员
const可以限定类中的数据成员,const数据成员一般用来描述对象中的常量。
在数据成员前添加const关键字就将其限定为常量。const数据成员在构造函数
的初始化列表中初始化。创建对象时初始化其中的const数据成员,之后的const
成员的值在对象的整个生成期中都不会改变。
例如:
class ClassA
{
private:
const int m_Num; //仅仅一个数值
public:
ClassA(int num) :m_Num(num){}
virtual ~ClassA(){}
};
ClassA a(10); ClassA b(20); //每个ClassA的对象都有保存一个const数值,在初始化后都不会改变
(5)const成员函数
和普通的内置数据类型对象一样,一个类的对象也可以限定为const;
如:
const int ival = 1024;
const ClassA a(10); //对象a为常量对象,修改该类对象会引起编译错误
将一个成员函数声明为const,表明这个成员函数不会修改对象的数据成员,能保证对象的常量性。
声明const成员函数的语法形式为:
返回类型 成员函数名 (参数表) const;
定义const成员函数的语法形式为:
返回类型 成员函数名 (参数表) const {函数体}
例如:
//ClassA.h
class ClassA
{
private:
int m_Num; //仅仅一个数值
public:
ClassA(int num) :m_Num(num){}
virtual ~ClassA(){}
void setNum(int num){ m_Num = num; } //设置m_Num的值
int getNum() const { return m_Num; } //得到m_Num的值
};
//main.cpp
#include<iostream>
using namespace std;
#include "ClassA.h"
int main(char argc, char* argv[])
{
const ClassA a(5); //const对象
a.getNum(); //OK
a.setNum(20); //error
return 0;
}
只有声明为const的成员函数才能被const对象调用。const对象不能调用非const成员函数,但是非const对象可以调用const成员函数。
const成员函数中不能修改类的数据成员,也不能调用其他非const成员函数,否则会引起编译错误。
const在限定成员函数时对其参数表产生了影响。ClassA类的成员函数的第一个隐含参数是ClassA*类型的this指针。但是const
ClassA对象的地址是const ClassA*类型的,用const ClassA对象调用非const 成员函数时,编译器报告的错误是:“参数类型不匹配:不能
将实参从const ClassA*转换为ClassA*"。这实际上反映的是隐含this指针类型错误。
const限定的成员函数其实是将const关键字作用于隐含的this指针,其类型成为了const ClassA*。因此编译器防止以任何方式
通过this指针来修改当前对象的状态,从而保证了对象其生成期间的常量性。