摘要:出現在左邊表示被指物是常量,出現在右邊表示指針自身是常量。沒問題改變的是所指物錯誤是在函數聲明時的應用令函數返回一個常量,往往可以降低因客戶錯誤導致的意外。總結將某些東西聲明為可以幫廚編譯器偵測出錯誤用法。
在學習c的過程中我們經常用#define來進行預處理操作,但#define并未被視作語言的一部分,因此也會帶來許多的問題。
? #define i? 5?
在這條預處理命令中i被定義為5,但是在編譯過程中所有的i都被替換為5,可能會導致i并沒有進入符號表中。當你使用這個常量進行編譯報錯時,并不會提示i出錯。而是會提到5這個數字。
如果對記號表不太理解可以看一下這篇文章
https://www.cnblogs.com/programnote/p/4729467.html
但是在使用const定義時并不會出現這種問題,因為你的i已經被保存在符號表。
當我們以常量替換#define時需要注意
1.定義常量指針時,因為常量定義需要放在頭文件中以便被其他的源碼所使用。
所以我們需要把指針聲明為const。對于在 * 左右表示的不同含義在下文中會有所提及。
這里給出一個例子:
const char* const name=“jam”;
但是在c++中我們已經學了string,所以用string替換會達到更好的效果
const std::string name("jam");
2.定義類的專屬常量
我們在定義class的專屬常量時需要將常量的作用域限制在class內,但是#define不能用來定義class的專屬常量,也不能提供任何的封裝性。?
?我們知道enum也可以用來定義常量,但是enum的行為比較像define而不像const,因為我們可以取得一個const的地址,而不能取得enum和#define的地址。如果你不想讓一個指針來指向你的某個整數常量,那么你可以試試enum;同時enum和#define一樣不會導致非必要的內存分配。
?使用#define來實現宏時雖然不會帶來函數調用的額外開銷,但會帶來許多麻煩
例如
#define? MAX(A,B) (A) > (B) ? (A) : (B)
只是看著這些括號就讓人很不舒服吧。
如果不加括號會帶來更多的麻煩
例如:
#define? ADD(a)? a+a
當兩個add相乘時結果會是多么糟糕。
當我們使用template inline函數時
template
inline void max(const T&a,const T&b)
{
f(a > b ? a : b );//函數內函數調用的實現,再次不多解釋
}這樣我們就不用擔心參數核算的問題了,另外max也是真正的函數遵循作用域和訪問規則。
總結:1.對于單純的常量,最好用const對象或enums替換;
? ? ? ? ?2.對于形似函數的宏,最好用inline函數替換。?
const用于告訴編譯器某個值保持不變,可以修飾class外部的global 或namespace中的常量,或者修飾文件、函數中的static對象。
const出現在*左邊表示被指物是常量,出現在*右邊表示指針自身是常量。
vector
v; const std::vector
::iterator iter=v.begin(); *iter=10;//沒問題改變的是iter所指物
++iter;//錯誤iter是const;
const在函數聲明時的應用:
令函數返回一個常量,往往可以降低因客戶錯誤導致的意外。
這里寫一段簡潔的代碼看一下
class ans{};
const ans operator*(const ans&lhs,const ans& rhs);
ans a b c;
if(a*b=c);//實際想做比較操作
我們在使用const作為返回值時,如果出現這種無意義的賦值操作就會報錯(一般情況不會報錯,使得許多人很苦惱)
在繼續const的使用說明前希望大家可以看一下這篇文章了解bitwise const和logical const
http://blog.sina.com.cn/s/blog_477141850101hooy.html
當const和non-const成員函數有著實質等價的實現時,令non-const版本調用const版本可以避免代碼重復。但是切記不可一用const版本調用non-const版本,因為const成員函數承諾絕不改變其對象的邏輯狀態。
例如
class text{public:const char& operator[](std::size_t position)const{...return text[position]}char& operator[](std::size_t position){...return text[position]}private:std::string t;}
當兩個函數的功能一樣時,可能會調用兩次,這樣會造成編譯時間,代碼膨脹等問題。
我們可以這么修改代碼
class text{public:const char& operator[](std::size_t position) const{...;return text[position];}char& operator[](std::size_t position){...;return const_cast
(static_cast (*this)[position];}; 轉型(cast)大家可以點擊上面鏈接查找資料。
如果不轉型為const那么non-const函數只會無窮的遞歸調用自己,注意我們寫的是操作符重載函數,將非const對象轉型為了const對象,這樣我們就避免了代碼重復。
總結:
1.將某些東西聲明為const可以幫廚編譯器偵測出錯誤用法。
2.const可以被施加于任何作用域內的對象、函數、函數參數、函數返回類型。
3.當const和non-const成員函數有著實質等價的實現時,令non-const版本調用const版本可以避免代碼重復。但是切記不可一用const版本調用non-const版本,因為const成員函數承諾絕不改變其對象的邏輯狀態。
這個方面就不多解釋了,直接總結一下吧
1.為內置型對象進行手工初始化,因為c++不保證初始化他們。
2.構造函數最好使用成員初值列,而不要再構造函數本體內使用賦值操作。初值列列出的成員變量,排列次序應該與class中的聲明次序相同。
例如:
class text{
public:text();
int myid;
string myname;
}
text::text(const std::int&id,const string& name):myid(id),myname(name)
{};
最好使用local static對象替換 non-local static對象。免除“跨編譯單元的初始化次序”問題。
?本篇文章的主要參考書籍是《effective c++》,用更短的篇幅來讓大家獲得相同的知識,同時也是我在學習《effective c++》時所做的一些總結,希望能幫到大家。同時我也會陸續將本書中的9個模塊全部更新完,喜歡的小伙伴們就關注一下我吧。希望在學習c++的路上能有更多的小伙伴
?
?
?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/122426.html
摘要:下面列舉了游戲開發中常見的崗位以及兩條常見的協作開發的流水線其實學習游戲引擎,前期對于任何崗位來說路線都是相似的,基本上就是一個熟悉基本操作理解基本概念拓展專業知識的過程。當然這不是絕對的,任何引擎的開始階段和大成階段都是相似的。 這是【游戲開發那些事】第51篇原創 前言:游戲引擎,表面...
摘要:上面需要了解的是這倆個版本都是破蛹成蝶的版本世界挑戰榜咋才前三還沒擠進去呀,你想想世界上有幾千中編程語言,在其中脫穎出來,可以說是天之嬌子,鳳毛麟角了。支持正版圖靈上面買吧,如果沒錢買盜版吧學完以后買本正版支持一下,創作不易是吧 ...
閱讀 2312·2021-11-17 09:33
閱讀 843·2021-10-13 09:40
閱讀 573·2019-08-30 15:54
閱讀 777·2019-08-29 15:38
閱讀 2416·2019-08-28 18:15
閱讀 2474·2019-08-26 13:38
閱讀 1840·2019-08-26 13:36
閱讀 2129·2019-08-26 11:36