【C++初阶】const 成员函数 取地址运算符重载超详解(六大默认成员函数收官篇)

📅 2026/7/21 8:15:30
【C++初阶】const 成员函数  取地址运算符重载超详解(六大默认成员函数收官篇)
系列文章目录构造函数超详解特性类型初始化方式易错避坑析构函数超详解误区、语法、调用时机、析构顺序拷贝构造函数超详解浅拷贝、深拷贝、拷贝构造 vs 赋值运算符重载、易错点赋值运算符重载 operator超详解深浅拷贝、自赋值判断、连续赋值原理、三法则、完整示例代码【C初阶】const 成员函数 取地址运算符重载超详解六大默认成员函数收官篇文章目录系列文章目录前言一、const 成员函数1. 什么是 const 成员函数2. 本质const 修饰的是 this 指针3. 调用规则权限只能缩小不能放大4. 什么时候该加 const 5. 高频易错点易错点 1const 成员函数里修改成员变量易错点 2函数声明和定义分离时const 要两边都加二、取地址运算符重载了解1. 两个版本的取地址重载2. 编译器生成的取地址重载有什么用3. 什么时候需要手写取地址重载4. 为什么要有两个版本总结前言前面我们已经系统学完了构造、析构、拷贝构造、赋值重载四大核心默认成员函数今天我们把剩下的两个收尾const 成员函数 取地址运算符重载。这两个知识点中const 成员函数是比较重要的高频知识点而取地址运算符重载属于 “了解” 的内容很多场景下编译器默认生成的就够用几乎不用我们手写。一、const 成员函数1. 什么是 const 成员函数在成员函数的参数列表后面加上const关键字这个函数就叫做const 成员函数。语法格式返回值类型 函数名(参数列表)const{// 函数体}代码示例Date 类的 Print 函数#includeiostreamusingnamespacestd;classDate{public:Date(intyear1,intmonth1,intday1){_yearyear;_monthmonth;_dayday;}// const成员函数只读打印不修改对象voidPrint()const{cout_year-_month-_dayendl;}private:int_year;int_month;int_day;};2. 本质const 修饰的是 this 指针在 const 成员函数里隐含的this指针被const修饰表示在这个函数内不能修改对象的任何成员变量。我们把隐藏的this指针写出来对比普通成员函数void Print(Date* const this)this指针本身不能改指向但指向的对象内容可以修改const 成员函数void Print(const Date* const this)this指针本身不能改指向的对象内容也不能修改用通俗的话理解就是普通成员函数像 “可编辑文档”你既能看也能改const 成员函数像 “只读文档”你只能看不能改任何内容。3. 调用规则权限只能缩小不能放大分四种场景逐一说明普通对象非 const可以调用普通成员函数也可以调用 const 成员函数原因从 “可修改” 变成 “只读”属于权限缩小是允许的。const 对象只能调用 const 成员函数不能调用普通成员函数原因const 对象本身就是 “只读” 的普通成员函数可能修改内容属于权限放大是不允许的。const 成员函数内部只能调用其他 const 成员函数不能调用普通成员函数普通成员函数内部既能调用普通成员函数也能调用 const 成员函数代码示例#includeiostreamusingnamespacestd;classDate{public:Date(intyear1,intmonth1,intday1){_yearyear;_monthmonth;_dayday;}// const成员函数只读打印不修改对象voidPrint()const{cout_year-_month-_dayendl;}private:int_year;int_month;int_day;};intmain(){Dated1(2024,7,5);// 普通对象d1.Print();// 普通对象调用const成员权限缩小合法constDated2(2024,8,5);// const对象d2.Print();// const对象调用const成员权限匹配return0;}如果我们给 Date 加一个普通的修改函数用const对象调用普通成员函数#includeiostreamusingnamespacestd;classDate{public:Date(intyear1,intmonth1,intday1){_yearyear;_monthmonth;_dayday;}// const成员函数只读打印不修改对象voidPrint()const{cout_year-_month-_dayendl;}// 新增普通成员函数可修改voidSetDay(intday){_dayday;}private:int_year;int_month;int_day;};intmain(){Date d1;// 普通对象d1.SetDay(5);// 普通对象调用普通成员函数constDate d2;// const对象d2.SetDay(10);// const对象调用非const成员函数return0;}d2.SetDay(10);会直接编译报错因为 const 对象不能调用非 const 成员函数。4. 什么时候该加 const 开发规范只要是只读、不修改成员变量的函数建议一律加上 const。比如打印函数Print()获取成员的 Get 函数GetYear()、GetMonth()比较运算符重载operator、operator计算类函数GetMonthDay()加 const 的好处提高安全性防止误修改成员变量提高通用性const 对象和非 const 对象都能调用代码更规范更加符合企业级工程项目。5. 高频易错点易错点 1const 成员函数里修改成员变量voidPrint()const{_day10;// 编译报错const成员函数不能修改成员cout_yearendl;}原因this指针是const的指向的内容不可修改。易错点 2函数声明和定义分离时const 要两边都加如果类内声明、类外定义两边都必须带 const否则不匹配// 类内声明voidPrint()const;// 类外定义voidDate::Print()const// 必须加const{cout_yearendl;}二、取地址运算符重载了解1. 两个版本的取地址重载取地址运算符有两个重载版本都属于默认成员函数编译器会自动生成普通对象版本Date* operator()const 对象版本const Date* operator() const解释Date* 前面的 const 是修饰返回值 Date* 后一个 const 才是修饰隐含的 this 指针classDate{public:// 普通对象取地址Date*operator(){returnthis;// return nullptr; // 特殊场景不想让别人拿到真实地址}// const对象取地址constDate*operator()const{returnthis;// return nullptr; // 特殊场景}private:int_year;int_month;int_day;};2. 编译器生成的取地址重载有什么用编译器自动生成的取地址重载功能非常简单直接返回this指针也就是对象本身的地址和我们直接用对象取地址的效果完全一样。#includeiostreamusingnamespacestd;classDate{public:Date(intyear1,intmonth1,intday1){_yearyear;_monthmonth;_dayday;}// const成员函数只读打印不修改对象voidPrint()const{cout_year-_month-_dayendl;}// 编译器自动生成取地址重载private:int_year;int_month;int_day;};intmain(){Date d1;coutd1endl;// 等价于 d1.operator()return0;}3. 什么时候需要手写取地址重载一般编译器默认生成的就够用了只有极其特殊的场景才会自定义不想让外部获取对象的真实地址故意返回nullptr或者假地址取地址时做一些额外操作比如日志统计。4. 为什么要有两个版本和 const 成员函数的规则一致普通对象调用普通版operator()返回普通指针const 对象调用 const 版operator() const返回 const 指针保证权限匹配不会出现权限放大。总结恭喜大家到这里C 类的 6 个默认成员函数我们就全部学完了最后麻烦大家点赞支持一下鼓掌。补充C11 之后又新增了移动构造和移动赋值两个默认成员函数属于进阶内容有时间我们再讲解。