目錄
一、前言
二、const成員函數(shù)?
??const修飾類的成員函數(shù)?
??問題1?
??問題2
??針對const成員函數(shù)的??济嬖囶}(重點?。。?/p>
??取地址及const取地址操作符重載
三、共勉
一、前言
?? 在我們前面學習的類中,我們會定義成員變量和成員函數(shù),這些我們自己定義的函數(shù)都是普通的成員函數(shù),但是如若我們定義的類里什么也沒有呢?是真的里面啥也沒嗎?如下:
class Date {};
? 如果一個類中什么成員都沒有,簡稱為空類??疹愔惺裁炊紱]有嗎?并不是的,任何一個類在我們不寫的情況下,都會自動生成6個默認成員函數(shù)。
【默認成員函數(shù)概念】:用戶沒有顯式實現(xiàn),編譯器會生成的成員函數(shù)稱為默認成員函數(shù)
?其中上次的博客已經(jīng)詳細的講解了構造函數(shù)&&析構函數(shù)的使用方法與拷貝構造函數(shù)和賦值運算符重載,所以本次博客將繼續(xù)深度的講解const成員函數(shù)問題?
二、const成員函數(shù)?
??const修飾類的成員函數(shù)?
【概念】:將
const
修飾的“成員函數(shù)”稱之為const成員函數(shù),const修飾類成員函數(shù),實際修飾該成員函數(shù)隱含的this指針,表明在該成員函數(shù)中不能對類的任何成員進行修改?
??問題1?
?假如我現(xiàn)在有一個日期類,并且有如下的Func函數(shù)即調用情況:
class Date { public: //構造函數(shù) Date(int year, int month, int day) { _year = year; _month = month; _day = day; } void Printf() { cout << _year << "年" << _month << "月" << _day << "日" << endl; } private: int _year; int _month; int _day; }; void Func(const Date& d) { d.Printf(); } int main() { Date d1(2023, 11, 1); d1.Printf(); Date d2(2023, 11, 2); Func(d2); return 0; }
此時卻出現(xiàn)了報錯,這是為什么呢?
很明顯,這里Func函數(shù)d的調用Print()出錯了,而d1調用Print()卻沒出錯,為何呢?
這里涉及到權限問題。我們先把實際調用過程中,隱含的this指針寫出來:
如果對 this指針不了解的朋友可以看這篇博客:this 指針詳解
Print()函數(shù)里的const修飾this本身,this不能修改,但是this可以初始化,接著我們要搞清楚&d1和&d的類型分別是啥:
- &d1:Date*
- &d:const Date*
- Date*傳給Date* const沒有問題,都是可讀也可修改,所以d1調用Print()不會出錯
- 而const Date* 指向的內容不能被修改,可是當它傳給Date*時就出錯了,因為Date*是可以修改的,這里傳過去會導致權限放大。所以當然d調用Print()函數(shù)報錯。
?
?解決辦法:?
加上const去保護this指向的內容,也就是在Date*的前面加上const:void Print(const Date* const this) { cout << _year << "年" << _month << "月" << _day << "日" << endl; }
但是這里又不能之間加上const,因為this指針是隱含的,你不能顯示的將const寫出來。因此,C++為了解決此問題,允許在函數(shù)后面加上const以達到剛才的效果:
?void Print() const// 編譯器默認處理成:void Print(const Date* const this) { cout << _year << "-" << _month << "-" << _day << endl; }
此時我const Date*傳給const Date*就是權限不變,自然不會出錯了,同樣我Date*傳給const Date*就是權限縮小也不會有問題。因為權限不能放大,只能縮小或不變。
正確的代碼:class Date { public: //構造函數(shù) Date(int year, int month, int day) { _year = year; _month = month; _day = day; } void Printf() const // void Printf(Date* const this) { cout << _year << "年" << _month << "月" << _day << "日" << endl; } private: int _year; int _month; int _day; }; void Func(const Date& d) { d.Printf(); // d.Printf(&d); } int main() { Date d1(2023, 11, 1); d1.Printf(); // d1.Printf(&d); Date d2(2023, 11, 2); cout << endl; Func(d2); return 0; }
?
???問題2
假如我們遇到如下,自定義類型的比較情況:
class Date { public: //構造函數(shù) Date(int year, int month, int day) { _year = year; _month = month; _day = day; } bool operator<(const Date& d) { if (_year < d._year || _year == d._year && _month < d._month || _year == d._year && _month == d._month && _day < d._day) { return true; } else { return false; } } private: int _year; int _month; int _day; }; int main() { Date d1(2023, 11, 1); const Date d2(2023, 11, 2); cout << endl; d1 < d2; d2 < d1; return 0; }
此時卻出現(xiàn)了報錯,這是為什么呢?
- 首先對于第一個比較來說
d1
和d2
都是權限的保持
- 接著對于第二個比較來說
d1
傳遞過去是權限的縮小,本來是可以修改了,現(xiàn)在不能修改;d2
傳遞過去就變成了【權限的放大】,原本的d2
是const,但是this指針并沒有加[const]
做修飾,所以就造成了【權限方法】的問題
? ? ? ? 那要怎么去做一個修改呢?此時就可以使用到我們上面所講到的【const成員函數(shù)】,為當前的隱藏形參
this
?加上一個const做修飾,此時就可以做到【權限保持】bool operator<(const Date& d) const
???針對const成員函數(shù)的常考面試題(重點?。。?/strong>
問題1:const對象 可以調用 非const成員函數(shù)嗎?
? ? ? ? 這個當然不可以。我們前面已經(jīng)說過了,若 const對象去調用非const成員函數(shù),會造成【權限放大】的現(xiàn)象,原本在類外const對象的內容是不可以修改的,但是到了函數(shù)內部卻有可以修改了,這是不被允許的
?問題2:非const對象 可以調用 const成員函數(shù)嗎?
? ? ? ? 這個當然是可以的。非const對象本身就是可讀可寫的,那在函數(shù)內部你要去修改或者不修改都不會有影響
?問題3:const成員函數(shù)內可以調用其它的非const成員函數(shù)嗎?
? ? ? ?
? ? ? ?不可以,const成員函數(shù)內部只能調用const成員函數(shù)。因為const成員函數(shù)內部的this指針已經(jīng)具有常屬性的,萬一這個非const成員函數(shù)去修改了成員變量的內容就會出問題了
?問題4:非const成員函數(shù)內可以調用其它的const成員函數(shù)嗎?
? ? ? ?可以,權限縮小
?
??取地址及const取地址操作符重載
class Date { public: //取地址&重載 Date* operator&() { return this; } //const取地址&重載 const Date* operator&()const { return this; } private: int _year; int _month; int _day; };
當然,如果我們自己不寫&重載,編譯器也會默認生成,可以通過打印來看看:
三、共勉
? ? ? ?? 以下就是我對【C++】類的默認成員函數(shù)----const成員函數(shù)的理解,如果有不懂和發(fā)現(xiàn)問題的小伙伴,請在評論區(qū)說出來哦,同時我還會繼續(xù)更新對C++ 類和對象的理解,請持續(xù)關注我哦!??!??
文章來源:http://www.zghlxwxcb.cn/news/detail-850594.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-850594.html
到了這里,關于【C++】類的默認成員函數(shù)----const成員函數(shù)(超詳細解析)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!