const指针:从后往前的读法
根据“左内右本”的原则
左内:当const在*的左边,如const int* p; 表示指针p所指向的内容是常量
右本:当const在*的右边,如int* const p; 表示指针p本身是一个常量
结合起来:const int* const p; 则表示指针p所指向的内容是常量,同时指针p本身也是一个常量。
int const *p//p是一个指针(*),指向常(const)整形
int* const p//p是一个常(const)指针,指向整形
const int const *p (因为都在*的左边,这样的做法没有意义)等同于int const *p 等同于 const int *p
int main()
{
int i = 1, j = 2;
int const *p = &i; //ok
// *p = 1; //error,p指向长整形
p = &j; //ok
int* const p1 = &i;
*p1 = 1;//ok
// p1 = &j;//error
const int const *p2 = &i; //vs2008 此处warnging ;多次使用同一类型限定符
// *p2 = 1; // error
p2 = &j; //ok
const int const *p3 = &i; //此处warnging ;多次使用同一类型限定符
// *p3 = 1; // error
p3 = &j; //ok
const int const *p4 = &i; //此处warnging ;多次使用同一类型限定符
// *p4 = 1; // error
p4 = &j; //ok
return 0;
}
类成员函数中const的使用: 一般放在函数体后,形如:void fun() const;
任何不会修改数据成员的函数都因该声明为const类型。如果在编写const成员函数时,不慎修改了数据成员,或者调用了其他非const成员函数,编译器将报错,这大大提高了程序的健壮性。如:
#include <iostream>
using namespace std;
class T
{
public:
T(int a = 0): m_iVal(a){}
void ShowVal() const
{
int i = m_iVal;
// i = GetVal();//error, const成员函数不能调用非const成员函数
cout << i << endl;
}
int GetVal()
{
return m_iVal;
}
private:
int m_iVal;
};
int main()
{
T t;
t.ShowVal();
return 0;
}
const修饰类的数据成员:class T
{
const int m_iVal = 1;//error
};
const数据成员只能在某个对象的生存期内是常量,相对整个类来说是可变的!不能在类声明的时候初始化const数据成员(对于非const数据成员同样适用),只能是构造函数中初始化!因为声明并不分配内存,定义才分配内存
想要建立在类中的恒定常量,可以使用枚举常量(枚举数据类型的隐含类型是整数,所以不能表示浮点数)
class T
{
enum{size1 = 10, size2 = 20};
int m_array[size1];
};
函数返回值采用“引用传递”的场合不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。如:
T
&operate = (const T &other);
然而const A& operator=(const A& a);这样的方式定义赋值函数式错误的。
因为当连续赋值时,问题就出现了
A a,b,c;
(a=b)=c;
因为a.operator=(b)的返回值是对a的const引用,不能再将c赋值给const常量。
const 成员函数 (Effective 条款3)
1) 使const接口容易被理解,即得知哪个函数可以修改哪个不行。无法修改Non-static成员
2) 使"操作const对象"成为可能
#include <iostream>
using namespace std;
class Student
{
private:
const int m_name;
public:
Student(): m_name(10){}
const int GetName() const { //无const报错
return m_name;
}
};
void main()
{
const Student s;
cout << s.GetName();
getchar();
}
对于logical constness情况 :(可以修改对象的某些位,在client无法察觉的情况下)
#include <iostream>
using namespace std;
class Student
{
private:
const int m_name;
public:
Student(): m_name(10){}
const int GetName() const {
return m_name;
}
mutable int m_sleepTime; // 即使在const成员函数中,这些成员也容易被更改
const int GetSleepTime(bool isSummer) const
{
if(isSummer)
m_sleepTime = 8;
else
m_sleepTime = 9;
return m_sleepTime;
}
};
void main()
{
const Student s;
cout << s.GetSleepTime(true);
getchar();
}
通过对成员变量添加mutable