1、const常量
2、const修饰函数参数
3、const修饰函数返回值
4、const数据成员(类中的常变量)
5、const成员函数
1、const常量
数返回const对象一旦被创建后其值就不能被改变,所以const对象必须初始化,初始值可以是任意复杂的表达式:
可以利用一个对象(不一定是常量对象)来初始化常量对象,常量对象也可以作其他对象的初始化:const int i = get_size();//T const int j = 42;//T const int k;//F,未经初始化的常量,编译错误
int k = 4;
const int j = k; //T
int h = j; //T
2、const修饰函数参数
对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传递”,目的是提高效率。
例如将void Func(A a) 改为void Func(const A &a)。
对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。
例如void Func(int x) 不应该改为void Func(const int &x)。
3、const修饰函数返回值
值传递方式的函数,由于函数会把返回值复制到外部临时的存储单元中,加const修饰没有价值:
e.g. int GetInt(void) ==> const int GetInt(void) (没意义)
A GetA(void) ==> const A GetA(void),其中A 为用户自定义的数据类型。(也没意义)
指针传递方式的函数,函数返回值即指针:
e.g. char *GetString(void)
加const 修饰,
e.g. const char *GetString(void)
那么函数返回值的内容不能被修改,该返回值只能被赋值给const修饰的同类型指针
e.g. const char *str = GetString(); (正确)
char *str = GetString(); (错误)
4、const数据成员
const 数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的,因为类可以创建多个对象,不同的对象其 const 数据成员的值可以不同;因此最好不要在类声明中初始化 const 数据成员(尽管可以在类中声明且初始化const数据成员,但是违背了类的常数据成员初衷)。
class base{
public:
base(){};
~base(){};
const int size = 100;//虽然没错,但是不建议在此初始化
}
//在main中,
int main()
{
base base1;//实例该对象
cout << base1.size << endl;
base base2;
cout << base2.size << endl;
}
const 数据成员的初始化最好在类构造函数的初始化表中进行,一般这么写:
class base{
public:
base(int s) : size(s){};//在构造函数中对常成员初始化
~base(){};
const int size;//只声明不初始化
}
//在main中,
int main()
{
base base1(100);//实例该对象,并给size赋值100
cout << base1.size << endl;
base base2(200);
cout << base2.size << endl;
}
那么如何创建对整个类都是恒定的常量呢?有两种方法,但是都与局限性:
第一种,通过枚举,局限在整形
第二种,通过静态常变量(声明即初始化)局限在:只能声明整数的静态常量
e.g. static const int size = 100;//T
其他任何类型都错误,e.g. static const double size = 100;//F
5、const成员函数
原则:任何不会修改数据成员的函数都应该声明为const类型,不慎修改了数据成员,将报错.
e.g.
class Stack
{
public:
void Push(int elem);
int Pop(void);
int GetCount(void) const; // const 成员函数,const关键字只能放在成员函数尾部
private:
int m_num;
int m_data[100];
};
int Stack::GetCount(void) const
{
++ m_num; // 编译错误,企图修改数据成员m_num
Pop(); // 编译错误,企图调用非const 函数
return m_num;
}
a. const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数.
b. const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的.
c.const成员函数不可以修改对象的数据,不管对象是否具有const性质.它在编译时,以是否修改成员数据为依据,进行检查.
d.