日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++中const——由一个例子想到的

發布時間:2025/5/22 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++中const——由一个例子想到的 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前天同學實現了《C++ Primer》中關于虛函數的一個例子,拿過來問我,代碼如下:

#include<iostream> #include<string> using namespace std;class Item{ public:Item(const string x,const double y){isbn=x;price=y;};virtual double net_price(size_t n) const{return n*price;};//可以去掉virtual體驗到第3、4行打印出來的區別virtual ~Item(){};string isbn; protected:double price; };class Bulk_Item:public Item{ public:Bulk_Item(const string x,const double y,const size_t z,const double w):Item(x,y),min_qty(z),discount(w){};double net_price(size_t n) const;//double get() const;//double get(); private:size_t min_qty;double discount; };double Bulk_Item::net_price(size_t n) const{if(n>=min_qty) return n*(1-discount)*price;else return n*price; }void print_total(const Item &it,size_t n){cout<<it.isbn<<"\tnumber sold: "<<n<<"\ttotal price: "<<it.net_price(n)<<endl; }int main(){Item it1("201307291540",16.5);cout<<it1.net_price(2)<<endl;Bulk_Item it2("201307291545",22.5,10,0.2);cout<<it2.net_price(20)<<endl;print_total(it1,4);print_total(it2,20);return 0; }

?

?同學的疑問是,如果去掉 Item 類定義中

virtual double net_price(size_t n) const{return n*price;};

?

一句中的 const 限定,則會在print_total 的定義行出現編譯錯誤

“Item::net_price”: 不能將“this”指針從“const Item”轉換為“Item &”

他覺得定義的 net_price 方法并沒有修改 Item 內的屬性,有沒有const限定詞應該是一樣的。 

但實際上,在print_total 的定義中,限定了引用 it 為 const, 這意味著該引用只能調用 Item 類內的 const方法,即:const限定的對象引用不能調用此對象中的非const方法。

進而,可以知道,C++中判斷一個方法是不是const,并不是檢測你在該方法中有沒有改變類的屬性,而只是簡單的看你有沒有const限定詞,有就是const方法,沒有就不是const方法。若有const限定詞,而在方法內你又試圖改變類的屬性,則編譯器會報錯。

?

那么,同名函數(包括參數相同),一個有const限定,一個沒有,是兩個函數還是一個函數?為了探究,在?Bulk_Item 的定義中增加兩個 get_price 函數,一個為const,一個為普通函數,然后在主函數里調用:

#include<iostream> #include<string> using namespace std;class Item{ public:Item(const string x,const double y){isbn=x;price=y;};virtual double net_price(size_t n) const{return n*price;};//可以去掉virtual體驗到第3、4行打印出來的區別virtual ~Item(){};string isbn; protected:double price; };class Bulk_Item:public Item{ public:Bulk_Item(const string x,const double y,const size_t z,const double w):Item(x,y),min_qty(z),discount(w){};double net_price(size_t n) const;double get_price() const{cout<<"get const"<<endl;return price;};double get_price(){cout<<"get Non const"<<endl;return price; };private:size_t min_qty;double discount; };double Bulk_Item::net_price(size_t n) const{if(n>=min_qty) return n*(1-discount)*price;else return n*price; }void print_total(const Item &it,size_t n){cout<<it.isbn<<"\tnumber sold: "<<n<<"\ttotal price: "<<it.net_price(n)<<endl; }int main(){Item it1("201307291540",16.5);cout<<it1.net_price(2)<<endl;Bulk_Item it2("201307291545",22.5,10,0.2);cout<<it2.net_price(20)<<endl;print_total(it1,4);print_total(it2,20); cout<<it2.get_price()<<endl;return 0; }

?

輸出結果為:

get Non const 22.5

可見,并沒有產生編譯錯誤,自動調用的是非const方法。故有無const會造成有兩個重載的函數,編譯后的函數名,除了函數名和參數,還加入了const限定詞。但調用時會優先選非const的函數(這是因為我們傳入的是非const對象it2,下面會看到,若傳入const對象,則自動調用const版本)。

接著,我們構造打印函數,如下:

#include<iostream> #include<string> using namespace std;class Item{ public:Item(const string x,const double y){isbn=x;price=y;};virtual double net_price(size_t n) const{return n*price;};//可以去掉virtual體驗到第3、4行打印出來的區別virtual ~Item(){};string isbn; protected:double price; };class Bulk_Item:public Item{ public:Bulk_Item(const string x,const double y,const size_t z,const double w):Item(x,y),min_qty(z),discount(w){};double net_price(size_t n) const;double get_price() const{cout<<"get const"<<endl;return price;};double get_price(){cout<<"get Non const"<<endl;return price; };private:size_t min_qty;double discount; };double Bulk_Item::net_price(size_t n) const{if(n>=min_qty) return n*(1-discount)*price;else return n*price; }void print_total(const Item &it,size_t n){cout<<it.isbn<<"\tnumber sold: "<<n<<"\ttotal price: "<<it.net_price(n)<<endl; }void print_price(const Bulk_Item &it){cout<<"print_price const"<<endl;cout<<it.get_price()<<endl; }void print_price(Bulk_Item &it){cout<<"print_price Non const"<<endl;cout<<it.get_price()<<endl; }int main(){Item it1("201307291540",16.5);cout<<it1.net_price(2)<<endl;Bulk_Item it2("201307291545",22.5,10,0.2);cout<<it2.net_price(20)<<endl;print_total(it1,4);print_total(it2,20);cout<<it2.get_price()<<endl; print_price(it2);return 0; }

?

輸出結果為:

print_price Non const get Non const 22.5

?

可見,(1)調用時,優先調用參數為非const的函數(因為傳入的it2是非const參數),編譯器不會在你傳入非const參數時調用const參數的函數(除非沒有非const版本),這是合理的,否則你不能改變你想改變的;(2)函數內,自動調用非const版本get_price(因為傳入的是非const引用,故優先調用get_price方法的非const版本)。

同理,如果傳入const 參數,如下:

#include<iostream> #include<string> using namespace std;class Item{ public:Item(const string x,const double y){isbn=x;price=y;};virtual double net_price(size_t n) const{return n*price;};//可以去掉virtual體驗到第3、4行打印出來的區別virtual ~Item(){};string isbn; protected:double price; };class Bulk_Item:public Item{ public:Bulk_Item(const string x,const double y,const size_t z,const double w):Item(x,y),min_qty(z),discount(w){};double net_price(size_t n) const;double get_price() const{cout<<"get const"<<endl;return price;};double get_price(){cout<<"get Non const"<<endl;return price; };private:size_t min_qty;double discount; };double Bulk_Item::net_price(size_t n) const{if(n>=min_qty) return n*(1-discount)*price;else return n*price; }void print_total(const Item &it,size_t n){cout<<it.isbn<<"\tnumber sold: "<<n<<"\ttotal price: "<<it.net_price(n)<<endl; }void print_price(const Bulk_Item &it){cout<<"print_price const"<<endl;cout<<it.get_price()<<endl; }void print_price(Bulk_Item &it){cout<<"print_price Non const"<<endl;cout<<it.get_price()<<endl; }int main(){Item it1("201307291540",16.5);cout<<it1.net_price(2)<<endl;Bulk_Item it2("201307291545",22.5,10,0.2);cout<<it2.net_price(20)<<endl;print_total(it1,4);print_total(it2,20);cout<<it2.get_price()<<endl;print_price(it2);const Bulk_Item it3("201307291546",44,10,0.2);print_price(it3);return 0; }

?

則會打印:

print_price const get const 44

?

說明,(1)傳入const參數會調用參數為const的函數,這是理所應當的;(2)在print_price里會調用const版本的get_price,這說明,如果我們對一個類,有同名的兩個函數,一個為const,一個非const,若用一個const對象引用來調用這個同名函數,則自動調用那個const函數。如下所示:

#include<iostream> #include<string> using namespace std;class Item{ public:Item(const string x,const double y){isbn=x;price=y;};virtual double net_price(size_t n) const{return n*price;};//可以去掉virtual體驗到第3、4行打印出來的區別virtual ~Item(){};string isbn; protected:double price; };class Bulk_Item:public Item{ public:Bulk_Item(const string x,const double y,const size_t z,const double w):Item(x,y),min_qty(z),discount(w){};double net_price(size_t n) const;double get_price() const{cout<<"get const"<<endl;return price;};double get_price(){cout<<"get Non const"<<endl;return price; };private:size_t min_qty;double discount; };double Bulk_Item::net_price(size_t n) const{if(n>=min_qty) return n*(1-discount)*price;else return n*price; }void print_total(const Item &it,size_t n){cout<<it.isbn<<"\tnumber sold: "<<n<<"\ttotal price: "<<it.net_price(n)<<endl; }void print_price(const Bulk_Item &it){cout<<"print_price const"<<endl;cout<<it.get_price()<<endl; }void print_price(Bulk_Item &it){cout<<"print_price Non const"<<endl;cout<<it.get_price()<<endl; }int main(){Item it1("201307291540",16.5);cout<<it1.net_price(2)<<endl;Bulk_Item it2("201307291545",22.5,10,0.2);cout<<it2.net_price(20)<<endl;print_total(it1,4);print_total(it2,20);cout<<it2.get_price()<<endl;print_price(it2);const Bulk_Item it3("201307291546",44,10,0.2);cout<<it3.get_price()<<endl;print_price(it3);return 0; }

?則會打印:

get const 44

?故而,鑒于有無const限定詞會造就兩個不同的函數,所以如果基類中有const,而繼承類中同名方法沒有const,則其實繼承類實現的是一個完全新的函數,而不是在覆蓋基類的方法。向上類型轉換時,會調用基類的方法,而不是繼承類中同名的非const方法,如下:

#include<iostream> #include<string> using namespace std;class Item{ public:Item(const string x,const double y){isbn=x;price=y;};virtual double net_price(size_t n) const{return n*price;};//可以去掉virtual體驗到第3、4行打印出來的區別virtual ~Item(){};string isbn; protected:double price; };class Bulk_Item:public Item{ public:Bulk_Item(const string x,const double y,const size_t z,const double w):Item(x,y),min_qty(z),discount(w){};double net_price(size_t n) ;private:size_t min_qty;double discount; };double Bulk_Item::net_price(size_t n) {if(n>=min_qty) return n*(1-discount)*price;else return n*price; }void print_total(const Item &it,size_t n){cout<<it.isbn<<"\tnumber sold: "<<n<<"\ttotal price: "<<it.net_price(n)<<endl; }int main(){Item it1("201307291540",16.5);cout<<it1.net_price(2)<<endl;Bulk_Item it2("201307291545",22.5,10,0.2);cout<<it2.net_price(20)<<endl;print_total(it1,4);print_total(it2,20);return 0; }

最后一行輸出為450而不是360。

同理,若基類方法無const,而繼承類中有,則向上類型轉換還是會調用基類的方法。

總結一下,主要有這么幾點:

1、const限定的對象引用不能調用此對象中的非const方法。

2、const關鍵詞限定的方法,則編譯器就認為它是const型的,即使它并沒有改變對象的任何屬性。若限定了const,又在方法內改變了屬性,則編譯器會報錯。

3、同名函數(參數也相同),一個有const限定,一個沒有,編譯器認為是兩個重載函數,不會報錯。這就意味著C++中編譯器生成函數名時,除了函數名、參數外還有const,由三者共同組成編譯后的函數名。

4、如上,兩個方法的方法名和參數完全相同,一個有const限定,一個沒有,則若你用const對象引用調用,會自動調用const版本的方法;若用非const對象引用調用,則會自動調用非const的版本。

5、同樣的函數,只是參數一個是const,一個非const,則你用const參數調用,會自動調用參數為const的版本;你用普通參數調用,會自動調用參數為普通參數的版本,若此時沒有非const的版本,它才會轉而調用const版本的。

6、如果基類中有const,而繼承類中同名方法沒有const,則其實繼承類實現的是一個完全新的函數,而不是在覆蓋基類的方法,向上類型轉換時,會調用基類的方法,而不是繼承類中同名的非const方法。

突然想到,學習一門語言的最好方式也就就是:寫一個這個語言的編譯器。這樣你就能對它的限制,它能做什么和不能做什么,你能用它做什么和不能做什么,有比較深刻的理解和記憶。推而廣之,人類語言有很多冗余性,語法限制也相對比較寬松,故人類語言的編譯器應該很難寫。若能寫一個人類語言的編譯器,那就是真正的自然語言理解。

轉載于:https://www.cnblogs.com/rolling-stone/p/3223454.html

總結

以上是生活随笔為你收集整理的C++中const——由一个例子想到的的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲第一天堂网 | 黄色性生活一级片 | 中文字幕资源网 | 咪咪成人网| 99热热热 | 日皮视频免费看 | 五月天婷婷基地 | sese国产| 无码人妻精品一区二区三区99日韩 | 黑丝美女啪啪 | 尤物毛片 | 中文字幕亚洲日本 | 日本欧美国产在线 | 99产精品成人啪免费网站 | 91美女在线观看 | 欧美啪啪小视频 | 久久99久久98精品免观看软件 | 国产一级片免费视频 | 美女扒开尿口给男人看 | 免费做a爰片77777 | 玖玖爱在线观看 | 国产亚洲一区二区三区四区 | 95在线视频 | 亚洲美女黄色片 | 亚洲aⅴ在线 | 国产精品无码久久久久久电影 | 亚洲一区二区国产精品 | 欧美在线色视频 | 天堂av在线免费观看 | youjizz日本人 | 天天爽夜夜 | 国产欧美在线视频 | 国产毛片久久久久久 | 国产精品日韩精品欧美精品 | 激情全身裸吻胸 | 波多野结衣家庭主妇 | 午夜合集 | 亚洲清纯唯美 | 久久精品1 | 天天射夜夜撸 | 看全色黄大色黄大片女一次牛 | 久久久午夜视频 | 日韩有色| 欧美夜夜骑 | 北条麻妃在线一区二区 | 欧美888 | 激情无码人妻又粗又大 | 国产看片网站 | 都市激情校园春色 | 献给魔王伊伏洛基亚吧动漫在线观看 | 五十路六十路 | 人妻在线一区二区三区 | 欧美老肥妇做爰bbww | 久久午夜神器 | a级片免费看 | 国产女同视频 | 99福利视频导航 | 色老板精品凹凸在线视频观看 | 91网页在线观看 | 亚洲观看黄色网 | 日本成人在线免费视频 | 久久国产露脸精品国产 | 国产成人精品三级麻豆 | 看片久久 | 亚洲免费视频网 | 医生强烈淫药h调教小说视频 | 大尺度摸揉捏胸床戏视频 | 免费午夜影院 | 在线免费观看视频黄 | 欧美精品第1页 | 伊人色影院 | 99精品人妻国产毛片 | 国产精品一区二区性色av | 韩日精品在线观看 | 欧美日韩黄色一区二区 | 国产一区二区三区视频免费在线观看 | 日本顶级大片 | 黄色小视频在线播放 | 日韩精品视频在线观看网站 | 国产精品电影网站 | 五月婷婷深爱 | 制服丝袜先锋影音 | 欧美色图亚洲色 | 亚洲精品合集 | 夜福利视频 | 夜夜久久 | 国产伦精品一区二区三区 | 青青操网 | 露出调教羞耻91九色 | 亚洲人精品 | 亚洲欧美日韩国产精品 | 欧美亚洲一区二区三区四区 | 超碰在线公开 | 国产高清免费 | 免费在线成人 | 亚洲欧美在线一区 | 日韩久久一区二区 | 亚洲在线一区 | 正在播放经典国语对白 |