一、作用
- const 修饰成员变量,定义成 const 常量,相较于宏常量(详见下文说明1),可进行类型检查,节省内存空间,提高了效率。
- const 修饰函数参数,使得传递过来的函数参数的值不能改变。
- const 修饰成员函数,使得成员函数不能修改任何类型的成员变量,mutable (详见下文说明2)修饰的变量除外,也不能调用非 const 成员函数,因为非 const 成员函数可能会修改成员变量。
说明1:
- 宏常量:用一个标识符来表示的常量;
- 宏定义(不能以;结尾):
#define 标识符 字符串
- const常量与define宏定义的区别:
- 编译器处理方式不同:const常量是在编译阶段确定其值;define宏是在编译预处理阶段进行替换。
- 类型和安全检查不同:const常量有具体的类型,在编译阶段会执行类型检查,可以避免一些低级的错误;define宏没有数据类型,只是进行简单的替换,不做任何类型检查。
- 内存占用:const 定义的常量占用静态存储区的空间,程序运行过程中只有一份;define 定义的宏常量,在程序中使用多少次就会进行多少次替换,内存中有多个备份,占用的是代码段的空间。
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数。因此,const 可以节省空间,避免不必要的内存分配。
#define PI 3.14159 //常量宏
const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 ......
double i=Pi; //此时为Pi分配内存,以后不再分配!
double I=PI; //编译期间进行宏替换,分配内存
double j=Pi; //没有内存分配
double J=PI; //再进行宏替换,又一次分配内存!
- 调试:const 定义的常量可以进行调试;define 定义的宏常量不能调试,因为在预编译阶段就已经进行替换了。
- const的优点:
- 有数据类型,在定义式可进行安全性检查。
- 可调式。
- 占用较少的空间。
说明2:
在C++中,mutable
也是为了突破const的限制而设置的。被mutable
修饰的变量,将永远处于可变的状态,即使在一个const函数中。
存在这样一种情况:只想修改某个成员变量,其余成员变量仍然希望被const保护。
#include <iostream>
class Person {
public:
Person();
~Person();
int getAge() const; /*调用方法*/
int getCallingTimes() const; /*获取上面的getAge()方法被调用了多少次*/
private:
int age;
char *name;
float score;
mutable int m_nums; /*用于统计次数*/
};
Person::Person()
{
m_nums = 0;
}
Person::~Person(){}
int Person::getAge() const
{
std::cout << "Calling the method" << std::endl;
m_nums++;
// age = 4; 仍然无法修改该成员变量
return age;
}
int Person::getCallingTimes()const
{
return m_nums;
}
int main()
{
Person *person = new Person();
for (int i = 0; i < 10; i++) {
person->getAge();
}
std::cout << "getAge()方法被调用了" << person->getCallingTimes() << "次" << std::endl;
delete person;
getchar();
return 0;
}
二、在类中的用法
const成员变量: const 成员变量只能在类内声明、定义,在构造函数初始化列表中初始化。原因是:const 成员变量只在某个对象的生存周期内是常量,对于整个类而言却是可变的,因为类可以创建多个对象,不同类的 const 成员变量的值是不同的。因此不能在类的声明中初始化 const 成员变量,类的对象还没有创建,编译器不知道他的值。
注:static const(静态常量)和const static(常量静态)可以在类内初始化。
class My {
private:
static const int a= 769;
const static int b = 222;
public:
My(){}
const 成员函数:
- 不能修改成员变量的值,除非有 mutable 修饰;只能访问成员变量。
- 不能调用非常量成员函数,以防修改成员变量的值。