重载运算符三个const的作用

文章详细解析了C++中const关键字在运算符重载函数中的三个不同位置的含义。第一个const表示返回值是常量;第二个const确保函数在使用参数时不会修改它;第三个const修饰this指针,允许对const对象调用该成员函数。通过示例代码展示了缺少第三个const导致的编译错误,强调了const对象不能调用非const成员函数的规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);
  }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值