const和指针的用法
情况1:const char*
- 形式:
const T* ptr
- 含义:
const
修饰指针指向的 对象(即T
类型对象)。 - 规则:
- 指针可以修改:指针本身可以指向其他地址(例如
ptr = &another_obj
)。 - 对象不可修改:通过该指针 不能修改 指向的对象(例如
ptr->member = value
会报错,除非成员本身是mutable
)。
- 指针可以修改:指针本身可以指向其他地址(例如
示例:
const char* ptr = &obj;
ptr = &another_obj; // 允许修改指针指向的地址
ptr->some_member = 10; // 错误!不能修改指向的对象
情况2:char* const
- 形式:
T* const ptr
- 含义:
const
修饰 指针本身(即指针是常量,不能指向其他地址)。 - 规则:
- 指针不可修改:指针的指向地址固定(例如
ptr = &another_obj
会报错)。 - 对象可修改:通过该指针 可以修改 指向的对象(例如
ptr->member = value
是允许的)。
- 指针不可修改:指针的指向地址固定(例如
示例:
char* const ptr = &obj;
ptr = &another_obj; // 错误!不能修改指针的指向
ptr->some_member = 10; // 允许修改对象内容
记忆技巧
-
位置决定修饰对象:
const
在*
左边(如const T*
):修饰指向的对象(对象是常量)。const
在*
右边(如T* const
):修饰指针本身(指针是常量)。
-
组合情况:
const T* const ptr
:指针和指向的对象都不可修改。
函数参数中的应用
在函数参数中:
-
const char* &idx_header
:- 传递的是指向常量对象的指针的引用。
- 函数内部可以修改指针的指向(如让指针指向另一个地址),但不可修改指针指向的对象的内容。
-
char* const &idx_header
:- 传递的是常量指针的引用(指针本身不可修改指向)。
- 函数内部无法修改指针的指向,但可以修改指针指向的对象的内容。
这种设计通过 const
的位置明确了数据的安全性,避免误操作。
const Point operator+(const Point &point) const{
}
尝试去理解const,然后搞懂为什么这里放置const。
const 用于修饰左边的东西(来自大佬的纠正),只有当其为最左边的修饰符时才会作用于右边的东西,使其为常量,不可被修改。参考链接
好了言归正传
1.第一个const 的位置后面是函数返回值类型,表明函数返回的是常量!
2.第二个const 的位置后面是函数参数,表明读取参数时,将其视为常量,保证当传参为const类型时也可接受,否则如果只是接受变量,那么就无法处理+常数的操作。
3.第三个const后面表面看没有东西,其实可以视为缺省了类自身,或者可以认为其修饰的是this指针。那么这里的意义是,使得调用operator+的这个对象可以是const类型。
注意: 这里一旦添加了第三个const后,那么重载函数会直接认为调用当前函数的对象为const类型,失去变量语义,也就是说这个函数内不可以修改非静态成员的值。
大佬的参考链接
笔者运行了第三const的代码后:
#include<bits/stdc++.h>
using namespace std;
struct Point{
int x,y;
Point(int a,int b):x(a),y(b){};
const Point operator+(const Point &tmp){
return Point(x+tmp.x,y+tmp.y);
}
};
int main(){
//freopen("in.txt","r",stdin);
const Point p1 = Point(10, 20);
Point p2 = Point(20, 30);
Point p3 = p1 + p2; // 不加第3个const,这里会报错,因为p1是常数
// 注意,这里p1是常量,p2是变量,由于重载了“+”
// 上一句代码等同于 p1.operator+(p2);
// 由p1调用的operator+函数,因此调用该函数的是个常数。
cout<<p3.x<<" "<<p3.y<<endl;
return 0;
}
报错信息为:
这里可以看到,重载运算符函数不匹配“const Point”与“Point”的相加类型,因为如果不加第三个const时,调用此运算符的对象是变量,而在C++中 const object-> 变量是不允许的,因为一旦变为变量,那么就意味着可以修改这个对象的内容,也就违背了const的定义,故报错。
额外知识:C++中变量->const object是允许的,作用范围仅为当前函数内,所以传参时即便加了第二个const,传递变量类型也不会报错。
疑问:
1.如果加了第一个const是否会导致p3无法修改呢?不会,只是p1+p2的返回值是常量类型,但是还有个赋值=操作,赋值之后,p3还是变量。
2. 添加了第三个const后,函数内不能修改非静态成员的值!
struct Point{
int x,y;
Point(int a,int b):x(a),y(b){};
const Point operator+(const Point &tmp) const{
x = 4; //这一行无法编译通过
return Point(x+tmp.x,y+tmp.y);
}
};