当我们在传入参数时(引用传递、指针传递),我们需要考虑该函数是否对传入的对象进行修改,如果不修改,则使用const修饰。这么做带来的好处是如果在函数中误操作对对象进行了修改,编译器会报错提示,可以降低出错的概率。
比如以下这个例子
//我们传入指针p,但是不想对p的内容进行修改,这是正常情况下我们的代码
void fun(Node* p){
//statement
return;
}
//我们可以考虑加上const修饰
void fun(const int* p){
//statement
//*p = 2;//假如我们误输入这条语句编译器会报错提示
return;
}
class Emax{
public:
Exam(){
m = new int [3];
memset(m,sizeof(m),0);
};
~Exam(){
delete m;
m = nullptr;
}
char& operator[](size_t position)//函数1
{
return m[position[;
}
const char& operator[](size_t position) const//函数2
{
m[position] = 1;
return m[position];
}
/*
char& 之前的 const 是修饰返回的 char& 也就是 m[position],不允许外部对其修改
参数后面的const是修饰本函数,表示本函数只允许const修饰的变量调用。在后面解释
*/
private:
int *m;
}
那么函数1和函数2的区别如下
Exam a;
cout<
讲完了const的修饰的好处,const修饰也有坏处,比如在写类的成员函数的时候一个功能要写两遍,一遍 const 型,一遍 non-const 型。为了解决这个问题,我们采用转换来解决这个问题
const char& operator[](size_t position) const//函数2
{
return m[position];
}
char& operator[] (size_t position)
{
return const_cast(static_cast(*this)[position]);
}
可能看到这里会有些懵逼,但是我们一层一层拆解
//当我们通过non-const对象调用[]重载的时候,我们想复用const的代码,则我们先要把本non-const对象转换为const对象,这就是最里层 static_cast,然后通过static_cast 调用 [] 重载,得到的结果是 const char&,然后将const char& 通过 const_cast 转换为 char&,得到我们想要的结果。
现在我们有一个指针p,我们用const修饰它,会有两种情况
//first
const void* p;
//second
void* const p;
我们把 p 比作我们的手,而 *p 比作我们手指向的东西。
第一种是const修饰 *p,也就是说 p是不能改变的,而 p是可以改变的,也就是说 p 指向的内容不能变,但是 p 本身的指向可以变。我手指向哪里哪里就不能变,但是我的手可以动。
*第二种const修饰的是 p ,p 不能改变,但是 p 可以改变,我的手不能动,但是手指向的东西可以变。
页面更新:2024-04-02
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号