C++中const修飾成員函數(shù)
一、const 成員函數(shù)的核心定義
const修飾成員函數(shù)時(shí),要寫在函數(shù)參數(shù)列表后、函數(shù)體前(有virtual則在virtual后),其核心作用是:保證該成員函數(shù)不會(huì)修改當(dāng)前對(duì)象的任何非靜態(tài)成員變量,且只能調(diào)用其他 const 成員函數(shù)。
語(yǔ)法格式:
// 聲明(類內(nèi))
返回值類型 函數(shù)名(參數(shù)列表) const;
// 定義(類外)
返回值類型 類名::函數(shù)名(參數(shù)列表) const {
// 函數(shù)體
}
二、為什么需要 const 成員函數(shù)?
核心目的是保證 “常量對(duì)象” 的只讀性—— 當(dāng)一個(gè)對(duì)象被聲明為const(常量對(duì)象)時(shí),編譯器要求它只能調(diào)用const成員函數(shù),防止對(duì)象被意外修改。
先看一個(gè)沒(méi)有 const 成員函數(shù)的反例:
#include <iostream>
using namespace std;
class Person {
public:
int age = 20;
// 普通成員函數(shù):可修改成員變量
void showAge() {
cout << "Age: " << age << endl;
// 即使沒(méi)修改,編譯器也認(rèn)為這個(gè)函數(shù)“可能修改”對(duì)象
}
};
int main() {
// 常量對(duì)象:不允許被修改
const Person p;
p.showAge(); // 編譯報(bào)錯(cuò)!常量對(duì)象不能調(diào)用普通成員函數(shù)
return 0;
}
報(bào)錯(cuò)原因:編譯器無(wú)法確定showAge()是否會(huì)修改p,因此禁止常量對(duì)象調(diào)用普通成員函數(shù) —— 而const成員函數(shù)就是用來(lái)告訴編譯器:“這個(gè)函數(shù)絕對(duì)不會(huì)修改對(duì)象,放心讓常量對(duì)象調(diào)用”。
三、const 成員函數(shù)的使用規(guī)則(核心)
1.基礎(chǔ)規(guī)則:const 成員函數(shù)不能修改非靜態(tài)成員變量
#include <iostream>
using namespace std;
class Person {
public:
int age = 20;
static int total = 0; // 靜態(tài)成員變量
// const成員函數(shù):只讀,不能修改非靜態(tài)成員
void showAge() const {
cout << "Age: " << age << endl; // 允許:僅讀取
// age = 30; // 編譯報(bào)錯(cuò)!const函數(shù)不能修改非靜態(tài)成員變量
total = 100; // 允許:靜態(tài)成員變量不屬于具體對(duì)象,不受const限制
}
// 普通成員函數(shù):可讀寫
void setAge(int a) {
age = a; // 允許修改
}
};
int main() {
// 1. 常量對(duì)象:只能調(diào)用const成員函數(shù)
const Person p1;
p1.showAge(); // 正常執(zhí)行
// p1.setAge(30); // 編譯報(bào)錯(cuò)!常量對(duì)象不能調(diào)用普通成員函數(shù)
// 2. 普通對(duì)象:既可以調(diào)用const成員函數(shù),也可以調(diào)用普通成員函數(shù)
Person p2;
p2.showAge(); // 正常執(zhí)行
p2.setAge(30); // 正常執(zhí)行
return 0;
}
2.進(jìn)階規(guī)則:const 成員函數(shù)只能調(diào)用其他 const 成員函數(shù)
class Person {
public:
int age = 20;
void func1() const {
func2(); // 編譯報(bào)錯(cuò)!const函數(shù)不能調(diào)用普通成員函數(shù)
func3(); // 允許:調(diào)用其他const成員函數(shù)
}
void func2() {
// 普通成員函數(shù)
}
void func3() const {
// const成員函數(shù)
}
};
原因:普通成員函數(shù) “可能修改對(duì)象”,而 const 成員函數(shù)承諾 “不修改對(duì)象”,因此不能調(diào)用有修改風(fēng)險(xiǎn)的普通成員函數(shù)。
3. 例外:mutable 成員變量可被 const 函數(shù)修改
mutable(可變的)修飾的成員變量,突破 const 的限制 —— 即使在 const 成員函數(shù)中,也能修改mutable成員(用于存儲(chǔ) “邏輯上不影響對(duì)象常量性” 的狀態(tài),比如緩存、計(jì)數(shù)):
#include <iostream>
using namespace std;
class Person {
public:
int age = 20;
mutable int visitCount = 0; // 可變成員:記錄訪問(wèn)次數(shù)
void showAge() const {
visitCount++; // 允許:mutable成員可被const函數(shù)修改
cout << "Age: " << age << ",訪問(wèn)次數(shù):" << visitCount << endl;
}
};
int main() {
const Person p;
p.showAge(); // 輸出:Age: 20,訪問(wèn)次數(shù):1
p.showAge(); // 輸出:Age: 20,訪問(wèn)次數(shù):2
return 0;
}
四、底層原理:const 修飾的是 this 指針
const 成員函數(shù)的本質(zhì),是修改了this指針的類型:
- 普通成員函數(shù)中,this的類型是:類類型* const(指針本身不可改,指向的對(duì)象可改);
- const 成員函數(shù)中,this的類型是:const 類類型* const(指針本身不可改,指向的對(duì)象也不可改)。
編譯器視角的偽代碼對(duì)比:
// 普通成員函數(shù):void showAge(Person* const this)
void Person::showAge() {
this->age = 30; // 允許:this指向的對(duì)象可改
}
// const成員函數(shù):void showAge(const Person* const this)
void Person::showAge() const {
this->age = 30; // 報(bào)錯(cuò):this指向的對(duì)象是const,不可改
}
核心:const成員函數(shù)的this指針是 “指向 const 對(duì)象的 const 指針”,因此無(wú)法通過(guò)this修改成員變量 —— 這也是 const 函數(shù)不能修改非靜態(tài)成員的底層原因。
五、const 成員函數(shù)的重載
const 成員函數(shù)可以和普通成員函數(shù)構(gòu)成重載,編譯器會(huì)根據(jù)調(diào)用對(duì)象是否為 const,選擇對(duì)應(yīng)的版本:
#include <iostream>
using namespace std;
class Person {
public:
int age = 20;
// 普通版本:供普通對(duì)象調(diào)用
void showAge() {
cout << "普通版本:Age = " << age << endl;
}
// const版本:供常量對(duì)象調(diào)用
void showAge() const {
cout << "const版本:Age = " << age << endl;
}
};
int main() {
Person p1; // 普通對(duì)象
p1.showAge(); // 調(diào)用普通版本
const Person p2; // 常量對(duì)象
p2.showAge(); // 調(diào)用const版本
return 0;
}
總結(jié)
核心作用:const 成員函數(shù)承諾 “不修改對(duì)象的非靜態(tài)成員變量”,讓常量對(duì)象可以安全調(diào)用;
關(guān)鍵規(guī)則:
- 不能修改非靜態(tài)成員變量(mutable成員除外);
- 只能調(diào)用其他 const 成員函數(shù);
- 可與普通成員函數(shù)構(gòu)成重載,編譯器根據(jù)對(duì)象是否 const 選擇版本;
底層本質(zhì):const 修飾的是this指針,使其變?yōu)閏onst 類類型* const,限制對(duì)對(duì)象的修改。
開發(fā)建議:只要成員函數(shù)不修改對(duì)象狀態(tài),就聲明為 const 成員函數(shù) —— 這是 C++“常量正確性” 的最佳實(shí)踐,能讓代碼更健壯、更易維護(hù)。
相關(guān)文章
c++ 讓程序開機(jī)自動(dòng)啟動(dòng)的方法
這篇文章主要介紹了c++ 讓程序開機(jī)自動(dòng)啟動(dòng)的方法,需要的朋友可以參考下2017-09-09
C++瓦片地圖坐標(biāo)轉(zhuǎn)換的實(shí)現(xiàn)詳解
常見的瓦片地圖有矩形、菱形、正六邊形幾種。此文章主要討論菱形瓦片,也就是大家常說(shuō)的2.5D,斜45度瓦片地圖。比如《紅警2》、《帝國(guó)時(shí)代2》都是采用這種技術(shù)2022-09-09
C++計(jì)算整數(shù)序列的最長(zhǎng)遞增子序列的長(zhǎng)度操作

