如把#define aspect_ratio 1.653
替換為const double aspectratio = 1.653
1. 定義常量指標。
將指標(而不是指標所指之物)宣告為const
例如,若在標頭檔案內定義乙個常量的(不變的)char*-based
字串,則必須寫兩次const
const
char
*const authorname =
"scott meyers"
;const std::string suthorname
("scott meyers");
//下面的更好一些
2. class專屬常量
為了將常量的作用域限制於class內部,且此常量至多只有乙份實體,必須使其成為class的乙個static成員
class
gameplayer
;//定義式,放在實現檔案裡,且由於宣告時獲得了初值,因此定義時不可再賦初值
const
int gameplayer::numturns;
//舊編譯器不允許static成員在其宣告時獲得初值
class
gameplayer
;//定義式,放在實現檔案裡
const
double gameplayer::fudgefactor =
1.35
;//當在編譯時需要乙個class常量值,則可用乙個屬於列舉型別代替
class
gameplayer
;//常量宣告式
int scores[numturns]
;//使用該常量..
.};
char greeting=
"hello"
;char
* p = greeting;
//非常量指標,非常量資料
const
char
* p = greeting;
//非常量指標,常量資料
char
*const p = greeting;
//常量指標,非常量資料
const
char
*const p = greeting;
//常量指標,常量資料
//以下兩者等價
voidf1(
const widget* pw)
;void
f2(widget const
* pw)
;
迭代器為const等同於宣告指標為const,表明這個迭代器不得指向不同的東西,但它所指的東西的值是可以改變的
如果希望迭代器所指的東西的值不可改變,需要const_iterator
std::vector<
int> vec;
const std::vector<
int>
::iterator iter = vec.
begin()
;*iter =10;
//正確
iter++
;//錯誤
std::vector<
int>
::const_iterator citer = vec.
begin()
;*citer =10;
//錯誤
citer++
;//正確
目的:確認該成員函式可用於const物件身上
兩個成員函式如果只是常量性不同,則可以被過載
class
textblock
char
&operator
(std::size_t position)
//用於非const物件
private
: std::string text;};
textblock tb
("hello");
cout<;//呼叫非const成員函式operator
const textblock ctb
("hello");
cout<;//呼叫const成員函式operator
void
print
(const textblock &ctb)
cout<;tb[0]
='x'
;//對於非const,兩個操作都沒問題
cout<;//正確
ctb[0]
='x'
;//對於const,操作錯誤,錯誤原因:對乙個const版的operator返回的乙個const char& 施行賦值動作
//non-const operator返回型別是乙個char的位址,不是char;
//如果對乙個返回值是char而不是char&的賦值。則是錯誤的
const成員函式不可更改物件內任何non-static成員變數
如果想在const函式裡改變non-static,則應使用mutable釋放掉non-static成員變數
class
ctextblock
;std::size_t ctextblock::
length()
const
return textlength;
}
當const和non-const成員函式有著實質等價的實現時,令non-const版本呼叫const版本可避免**重複,const不能呼叫non-const
class
textblock
char
&operator
(std::size_t position)
//用於非const物件
private
: std::string text;
};
class
phonenumber
;class
abentry
;abentry::
abentry
(const std::string& name,
const atd::string& address,
const std::list
& phones)
//使用成員初始列替換賦值動作
abentry::
abentry
(const std::string& name,
const atd::string& address,
const std::list
& phones)
:thename
(name)
,theaddress
(address)
,thephones
(phones)
,numtimescounsulted(0
)//初始化
//使用default構造乙個成員變數,可以使用成員初值列,只要指定無物作為初始化實參即可
abentry::
abentry
(const std::string& name,
const atd::string& address,
const std::list
& phones)
:thename()
,theaddress()
,thephones()
,numtimescounsulted(0
)//初始化
c++有著十分固定的「成員初始化次序」,次序總是相同,base classes更早於其derived classes被初始化,而class的成員變數總是以其宣告次序被初始化
static物件:在函式內部的static物件被稱為local static物件(因為它們對函式而言是local),其他的static物件稱為non-local static物件
編譯單元:單一原始碼檔案加上其所含入的標頭檔案(#include files)
至少有兩個原始碼檔案,每乙個至少有乙個non-local static物件(即該物件是global或者位於namespace作用域內,抑或在class內或file作用域內被宣告為static
問題:如果某編譯單元內的某個non-local static物件,它所用到的這個物件可能尚未被初始化
例如
class
filesystem
;extern filesystem tfs;
//位於golbal或者namespace作用域內
class
directory
;directory::
directory
(params)
directory tempdir
(params)
;//以上是錯誤的
//正確:將non-local換為local,使用函式返回的「指向static物件」的references而不再使用static物件自身
class
filesystem
;filesystem&
tfs(
)class
directory
;directory::
directory
(params)
directory&
tempdir()
找工作之Effective C
1 盡量以const,enum,inline替換 define 2 const出現在星號左邊,表明指物是常量 出現在星號右邊,指標是常量。3 mutable修辭可以突破const限制,在被const修辭的函式裡面也能被修改 4 運用const成員函式實現non const版本可以避免 重複 5 co...
Effective C 之導讀部分
宣告 文中內容收集整理自 effective c 本內容在作者現有能力的基礎上有所刪減,另加入部分作者自己的理解,有紕漏之處敬請指正。目錄 1.術語 宣告和定義 初始化值傳遞和const引用傳遞 2.命名習慣 3.關於執行緒 4.tr1和boost 1.宣告式 是告訴編譯器某個東西的名稱和型別,而略...
effective c 閱讀條款之六
還是自願管理的東西 上次說的是關於raii class的一些知識,這裡補充一下感受,對於auto ptr 這個的操作來說 主要的物件還是動態的非陣列類的堆的物件,對於tr1 shared ptr 來說的話,操作的物件可以是其他的。下面說本 次的一些的收穫 1.對於raii class的複製函式的處理...