Effective C 之const的用法

2021-10-03 16:24:11 字數 4754 閱讀 8063

如把#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的複製函式的處理...