C++11 上下文關(guān)鍵字的具體實踐
前言
熟悉C++11的朋友都知道,C++有大概83個左右的關(guān)鍵字。
一、關(guān)鍵字是什么?
關(guān)鍵字(keyword)屬于保留字,是整個語言范圍內(nèi)預先保留的標識符。每個C++關(guān)鍵字都有特殊的含義。經(jīng)過預處理后,關(guān)鍵字從預處理記號(preprocessing-token)中區(qū)別出來,剩下的標識符作為記號(token),用于聲明對象、函數(shù)、類型、命名空間等。不能聲明與關(guān)鍵字同名的標識符
二、使用步驟
1.簡單例子
這里舉一些簡單例子,比如定義變量使用的類型關(guān)鍵字:int,float,double這些。
代碼如下(示例):
#include <iostream> int main(){ ?? ?int a = 0; ?? ?float b = 1.0; ?? ?double c = 2.0; ?? ?return 0; }
這里main使用的是不帶參數(shù)的版本。其他的關(guān)鍵字有各自的用法,由于C++語法體系比較復雜,只針對一些特殊的做說明。
像int這種內(nèi)置類型不需要引用名字空間
2.錯誤例子
關(guān)鍵字是保留字,不能用來當變量名和函數(shù)名或者諸如名字空間名字、類名等等命名。說白了編譯器正式通過解析關(guān)鍵字來理解語法結(jié)構(gòu),如果允許濫用關(guān)鍵字無疑會讓編譯器無法正常工作。
代碼如下(示例):
#include <iostream> int main(){ ?? ?int int = 0; ?? ?float float = 1.0; ?? ?double double = 2.0; ?? ?return 0; }
這里把int、float和double當作了普通變量名,IDE會報錯提醒你,編譯也無法通過。不過這并不意味著變量名中不能出現(xiàn)關(guān)鍵字的影子,請看下面的例子:
#include <iostream> int main(){ ?? ?int _int = 0; ?? ?float _float = 1.0; ?? ?double _double = 2.0; ?? ?return 0; }
加了下劃線的關(guān)鍵字就不是關(guān)鍵字了,就是普通變量了,可以正常編譯。
注意:不要濫用雙下劃線,有些內(nèi)置宏是以雙下劃線開頭的。比如:__cplusplus,建議這種帶關(guān)鍵字的變量名還是要少用或者不用,以免出現(xiàn)錯誤。
三、特殊關(guān)鍵字
終于還是到重頭戲了,關(guān)鍵字本身的使用沒什么好大書特書的,需要注意的上面已經(jīng)說的夠詳細了。其他關(guān)鍵字的使用方法只要參考C++11的語法就行了。
接下來說幾個特殊的“關(guān)鍵字”
1.export關(guān)鍵字
這個是C++11名副其實的關(guān)鍵字,只不過是個“未使用關(guān)鍵字”,暫時沒有被賦予特殊的含義。但是,你仍然不能濫用它,比如:命名一個變量,還是和上面的所有關(guān)鍵字一樣編譯不通過。
2.override關(guān)鍵字
這個關(guān)鍵字比較特殊,它是用在“運行時多態(tài)”的“上下文關(guān)鍵字”。注意這個上下文關(guān)鍵字,它有特殊含義,而又跟其它關(guān)鍵字不太一樣。你比如,最顯著的差別就是它可以被用來命名變量,而且可以編譯通過。
#include <iostream> int main(){ ?? ?int override = 0; ?? ?return 0; }
可以編譯通過,使用起來也沒問題。這個是歷史遺留問題,因為最早的時候還沒有override這個關(guān)鍵字,之前的老代碼中程序員大量使用這個命名變量,所以后來C++標準就把它定義為上下文關(guān)鍵字了。意思就是只有在特殊的場景下才有特殊含義,這個特殊含義就是“派生類復寫基類的virtual方法”,這個override關(guān)鍵字甚至可以不用寫,只不過IDE可能會給你個warning。
請看下面的例子:
#include <iostream> class X { public: ? ? virtual void print() const; }; void X::print() const { ? ? std::cout << "X::print()" << std::endl; } class Y : public X { public: ? ? void print() const; }; void Y::print() const { ? ? X::print(); ? ? std::cout << "Y::print()" << std::endl; }
上面的寫法就是不帶override。但是,實際上是Y復寫了X的print方法。建議不要這么寫,加上override作為標識,讓人一眼就能看出來這個方法是復寫的基類方法!
請看完美寫法:
#include <iostream> class X { public: ? ? virtual void print() const; }; void X::print() const { ? ? std::cout << "X::print()" << std::endl; } class Y : public X { public: ? ? void print() const override; }; void Y::print() const { ? ? X::print(); //這個如果不需要可以去掉 ? ? std::cout << "Y::print()" << std::endl; }
仔細觀察能發(fā)現(xiàn)區(qū)別,const無論聲明還是定義都是要加上的,override只需要在聲明中加上,不需要再定義上加上,因為它“不是函數(shù)的一部分”。
重要的一點:override必須放在函數(shù)聲明的最后位置,比如上面的例子,必須放在const后面。否則,編譯無法通過。
我們今天不是來討論運行時多態(tài)的用法的,所以更復雜的運行時多態(tài)本篇文章不討論,我們只討論“上下文關(guān)鍵字”和“保留關(guān)鍵字”之間的差別。
3.final關(guān)鍵字
用法和override不一樣,不過同樣可以作為一個變量名而被編譯通過。
沒錯,final也是“上下文關(guān)鍵字”。final主要用在“阻止進一步派生”,看起來和override是相反的功能,其實不是這樣的,無論有沒有override這個關(guān)鍵字,派生行為都是現(xiàn)實存在的一種語法;而final恰巧能夠阻止進一步派生。
請看代碼:
#include <iostream> class X { public: ? ? virtual void print() const; ? ? virtual void test() const final; }; void X::print() const { ? ? std::cout << "X::print()" << std::endl; } void X::test() const { ? ? std::cout << "X::test()" << std::endl; } class Y : public X { public: ? ? void print() const override; ? ? void test() const override;//這句編譯不通過 }; void Y::print() const { ? ? X::print(); ? ? std::cout << "Y::print()" << std::endl; }
仍然是延續(xù)剛才的代碼,print已經(jīng)override了,我們不用管。X的test標記為final,在Y中嘗試override就會報錯,原因是test被標記為final。
這個時候你有兩個選擇:1就是將final去掉;2就是將Y的test代碼去掉。兩種選擇都可以編譯通過。
和override一樣,final也是只出現(xiàn)在函數(shù)聲明里,不會出現(xiàn)在函數(shù)定義里,要不然編譯不通過。
特別說明:final不能修飾純虛函數(shù),因為純虛函數(shù)必須被復寫。
另外:virtual出現(xiàn)在函數(shù)聲明的前面,overide出現(xiàn)在函數(shù)聲明的后面,順序不能搞錯。如果virtual和overide在派生類的函數(shù)中同時出現(xiàn),只需要保留override即可。如果override和final同時出現(xiàn),只需要保留final即可。
總結(jié)
到此這篇關(guān)于C++11 上下文關(guān)鍵字的具體實踐的文章就介紹到這了,更多相關(guān)C++11 上下文關(guān)鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++中volatile和mutable關(guān)鍵字用法詳解
這篇文章主要介紹了C++中volatile和mutable關(guān)鍵字用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-02-02