const限定符:
const 就是限定后面接着的内容为不可改变,const 可限定*,&,变量名
const 在类中的使用,有几点总结如下:
1.const 可以给成员函数和成员变量使用,成员函数加在函数尾部。
2.const 成员变量必须使用初始化列表来初始化,只能访问,不能修改。
3.const 成员函数可以和非const 成员函数同名同参数。
4.const 成员函数内可以访问成员变量,不能修改成员变量。
5.const 对象可以访问成员变量,不能修改成员变量。
在C++中,mutable也是为了突破const 的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const 函数中。
非指针的变量:const放在变量名前和const放在类型前面意义是一样的,都是限定的变量的值不能修改,也叫做常量。
int const x = 100;
const int y = 100; // const在变量名前和在类型前面意义是一样的,
x = 101; // 编译出错,x不能修改值
y = 101; // 编译出错,y不能修改值
int a[10] = {0}; // 数组变量
for ( int i=0; i<10; i++ )
{
a[i] = i;
}
int const b[10] = {0}; // 数组常量
for ( int i=0; i<10; i++ )
{
b[i] = i; // b被const限定,不能修改值
}
指针的变量:
const放在*前面表示限定指针的地址里的值,即不能修改指针的值,也叫做常量指针,但是可以通过修改指针的地址来达到修改指针的值。
const放在*后面表示限定指针的地址,即不能修改指针的地址,也叫做指针常量,只能修改指针的值。)
int* const book1 = NULL; // 指针book1的地址不能修改
int const *book2 = NULL; // 指针book2的值不能修改
const int *book3 = NULL; // 指针book3的值不能修改
const int* const book4 = NULL; // 指针book3的值和地址都不能修改
int* p = new int(0);
book1 = p; // error: 不可以修改指针指向的地址
book2 = p; // 可以修改指针指向的地址
book3 = p; // 可以修改指针指向的地址
book4 = p; // error: 不可以修改指针指向的地址
*book1 = 1; // 可以修改指针指向的值
*book2 = 2; // error: 不可以修改指针指向的值
*book3 = 3; // error: 不可以修改指针指向的值
*book4 = 4; // error: 不可以修改指针指向的值
typedef里面使用const:
下面代码中 CPTR_B1等同CPTR_B2,但是CPTR_A1不等同CPTR_A2。
A1,B1,B2= *const,A2=const* 估计是多次typedef的解析重组导致,编译器在解析A1的typedef时,先解析CHARS,就把char*放到前面,第二次解析CPTR_A1,就变成了char* const
#include <stdio.h>
typedef char* CHARS;
typedef const CHARS CPTR_A1; // 指针常量
typedef const char* CPTR_A2; // 常量指针
typedef CHARS const CPTR_B1; // 指针常量
typedef char* const CPTR_B2; // 指针常量
int main()
{
char* p = new char('a');
CPTR_A1 pA1 = NULL;
CPTR_A2 pA2 = NULL;
pA1 = p; // 不可以修改地址
pA2 = p; // 可以修改地址
*pA1 = 'A'; // 可以修改值
*pA2 = 'A'; // 不可以修改值
CPTR_B1 pB1 = NULL;
CPTR_B2 pB2 = NULL;
pB1 = p; // 不可以修改地址
pB2 = p; // 不可以修改地址
*pB1 = 'A'; // 可以修改值
*pB2 = 'A'; // 可以修改值
}
引用:
引用就是另一个变量的别名
int A = 0;
int& x = 1; // 失败,没有指向的引用,
int& y = A; // j等于是A的别名称
常量引用,这个引用不能改变值,也不能改变引用的对象。
int& const j,这种写法编译的时候好像把const给忽略,这里const能限定的只有&,所以&放到const之后const就无效了。
#include <stdio.h>
int main()
{
int A = 0;
int B = 0;
const int& i = A; // 常量引用,表示这个引用不能修改值,也不能成为别的变量的引用
int& const j = A;
i = 2; // 失败,常量引用,不能修改值
i = B; // 失败,常量引用,不能成为别的变量的引用
j = 3;
j = B;
}
指针引用和指针引用常量(不知道这个怎么叫)
#include <stdio.h>
int main()
{
int A = 0;
int B = 0;
int* p = &A;
int* &q = p; // q是p的引用
q = &B; // 可以修改地址
*q = 1; // 可以修改值
int* const &q1 = p; // q1是p的指针引用常量
//q1 = &B; // 不可以修改地址
*q1 = 1; // 可以修改值
}
const在类中
#include <stdio.h>
class A
{
public:
A();
public:
int func(int i)
{
m_i1 = i;
i = m_i2;
// m_i2 = i; // const成员变量不能修改
return 0; // const成员变量可以访问
}
int func(int i) const // const成员函数可以和非const成员函数同名同参数
{
i = m_i1; // const成员函数 可以访问非const成员变量
i = m_i2; // const成员函数 可以访问const成员变量
// m_i1 = i; // const成员函数 不可以修改非const成员变量
// m_i2 = i; // const成员函数 不可以修改const成员变量
return 1; // 只能访问const成员变量,不能修改成员变量
}
int func_const(int i) const
{
i = m_i1; // const成员函数 可以访问非const成员变量
i = m_i2; // const成员函数 可以访问const成员变量
// m_i1 = i; // const成员函数 不可以修改非const成员变量
// m_i2 = i; // const成员函数 不可以修改const成员变量
return 2; // 只能访问const成员变量,不能修改成员变量
}
public:
int m_i1;
//int const m_i1; // const成员函数 不可以和非const成员函数同名
int const m_i2;
};
A::A(): m_i1(8),
m_i2(8) //必须使用初始化列表来初始化 const成员变量
{
}
int main()
{
int iRet = 0;
A a;
iRet = a.func(1);
iRet = a.func_const(10);
iRet = a.m_i1;
iRet = a.m_i2;
a.m_i1 = 1;
//a.m_i2 = 2; // error C3892: “a”: 不能给常量赋值
A const a1;
iRet = a1.func(1); // const实例调用的是const版本的func
iRet = a1.func_const(10);
iRet = a1.m_i1;
iRet = a1.m_i2;
//a1.m_i1 = 1; // error C3892: “a1”: 不能给常量赋值
//a1.m_i2 = 2; // error C3892: “a1”: 不能给常量赋值
}