一、指针和const
总体来说:如果关键字const出现在星号(*)左边,表示被指物是常量;如果出现在星号右边,表示指针自身是常量;如果出现在星号两边,表示被指物和指针两者都是常量。
1、const int *p:指向常量的指针(pointer to const)
(1)、指向常量的指针不能修改其所指对象的值;
const int *p:const int 修饰*p,*p是常量,不能再赋值,而p可以赋其他变量的地址,此处const int 与int const位置没有区别;
(2)、要存放常量对象的地址,只能使用指向常量的指针;也可以将普通的对象地址赋值给指向常量的指针,但是不能通过指向常量的指针来修改这个普通变量的值。
<span style="font-family:Microsoft YaHei;">#include <iostream>
using namespace std;
int main()
{
//(1)指向常量的指针不能修改其所指对象的值;
int i = 10;
int j = 20;
const int *p;
int const *q;
/*const int 修饰*p,*p是常量,不能再赋值,而p可以赋其他变量的地址 */
p = &i;
//*p = j; //错误 ,不能修改指向常量的指针的值(*p)
p = &j; //正确 ,可以向指向常量的指针赋其他地址(p)
cout<<*p<<endl;
/*int 与 const 的位置没有关系*/
q = &i;
q = &j;
cout<<*q<<endl;
//2、要存放常量对象的地址,只能使用指向常量的指针;
const double cpi = 3.14; //pi是一个常量
//double *ptr = &cpi; //错误:ptr是一个普通指针
const double *cptr = &cpi; //正确
//*cptr = 42.1; //错误:*cptr是常量
cout<<*cptr<<endl;
double pi = 3.1415; //pi是普通变量
const double *pt = π //正确,但是同样不能通过*p修改pi的值
return 0;
}</span>
2、int* const p:常量指针(const pointer)
(1)、指针本身定义为常量,常量指针必须初始化;
(2)、不能直接将const int*类型指针,赋值给int* 类型的指针;
<span style="font-family:Microsoft YaHei;">#include <iostream>
using namespace std;
int main()
{
//(1)\
int i = 10;
int j = 20;
//const 修饰p,不变的是指针本身的值,而非指向的那个值
//int* const p; //错误信息:uninitialized const 'p'
int* const p = &i; //正确初始化
//p = &j; //错误 ,常量指针必须初始化,而且初始化后(存放在指针中的地址)不能再改变
*p = j; //正确,可以修改指针指向对象的值,但是不能改变指针指向的地址
cout<<*p<<endl;//输出为j的值20
//(2)\
const int b = 200;
//&b为const int*类型指针,而ptr为int* 类型的指针,不能直接赋值
//int* const ptr = &b; //错误:直接将const int* 类型的指针赋值给int *类型
int* const ptr1 = (int *)&b; //正确:通过强制转换初始化
cout<<*ptr1<<endl; //输出为b的值200
return 0;
}</span>
二、this指针与const
在C++的类成员函数中,在成员函数的开始执行前会构造一个 this 指针。默认情况下,this的类型是指向类类型非常量的常量指针,即Test *const this(Test为类名),与前面2中讨论的常量指针类似。此时,我们的常量对象(const Test*)不能直接访问普通的成员函数(Test*),因此需要将普通成员函数声明成常量成员函数(this声明成const Test* const this)。
<span style="font-family:Microsoft YaHei;">#include <iostream>
using namespace std;
class test
{
public:
test():data(1)
{};
//普通成员函数
void print()
{
//使用this指针输出成员变量
cout<<this->data<<endl;//输出1
//this的类型位Test* const this
//类似与上面的常量指针,可以改变其指向变量的值,
//但是不能改变this指向的地址
this->data = 20; //正确:常量指针可以改变*this的值;
cout<<this->data<<endl; //输出20;
const test t;
//this = (Test*) &t; //错误,不能修改常量指针所指的地址
}
//常量成员函数
//通过常量成员函数,将this声明成const Test* const。
void show() const
{
cout<<this->data<<endl;
}
private:
int data;
};
int main()
{
test t;
t.print(); //正确:调用普通的成员函数,打印对象的私有成员变量
t.show(); //正确:普通对象调用常量成员函数
const test ct;
//ct.print(); //错误:使用了const test* const this类型的指针调用了test* this,类似const int *与 int *
ct.show(); //正确,通过常量成员函数,将this声明成const Test* const。
return 0;
}</span>