const是一件奇妙的事情,它指定乙個語義約束,而編譯器會強制執行這項約束,它允許你告訴編譯器或者其他程式設計師某值應該保持不變。
你可以用const修飾class內部的static和non-static成員變數,你也可以指出指標之身或者是指標所指物,或者兩個都是。
比如:char greeting = 「hello」;
char *p = greeting ; //non-const pointer , non-const date;
const char *p = greeting ; //non-const pointer , const date
char * const p = greeting; // const pointer , non-const date
const char * const p = greeting ; / / const pointer , const date
const 在*號左邊,表示指向物為常量, 在*號右邊,表示指標為常量。
比如 void f1(const widgh* pw);
void f2(widgh const * pw);
兩個都表示乙個指標, 並且指向乙個常量的widgh物件
stl迭代器系是以指標為根據塑造出來的,所以迭代器就是乙個t*指標。申明迭代器為const就像宣告指標為const一樣 (宣告乙個 t* const 指標),表示迭代器不得指向不同的東西,但是他們指向的東西是可以修改的。如果希望迭代器指向的東西是不可以被修改的(即希望stl模擬乙個const t* 型別的指標),你需要傳遞乙個const_iterator 。
std::vectorvec;
const std::vector::iterator iter = vec.begin(); // t* const
*iter = 10; //ok
iter++; // error
std::vectorconst_iterator citer = vec.begin(); //const t*
*citer = 10 ; //error
iter++ ; //ok
const最具有威力的用法是面對函式宣告時的應用。在乙個函式宣告式中,const可以和函式返回至,各引數,函式自身產生關聯。
令函式返回乙個常量,可以避免很多錯誤,而不至於放棄安全性和高效性。
比如:class rational(....);
const tational operator* (const tational & lhs , const tational &rhs);
假如你想要做乙個比較,而錯誤的打字為
if(a * b = c)...
如果a , b都是內建型別,這樣的**直接就是不合法 , 而乙個良好的使用者自定義型別的特徵可以避免無端的與內建型別不相容 , 因此允許對兩值乘級做賦值動作也沒什麼意思了。將operator*的回傳值宣告為const可以預防那個沒意思的賦值動作。
將const實施與成員函式的目的就是為了確認該成員函式可以作用於const身上。這一類成員函式之所以基於兩點:1.他們使class介面容易理解。因為得知哪個函式可以改動內容而哪個函式不行,這非常重要。 2.他們使操作const物件成為可能。這對於編寫高效**是個關鍵
考慮以下**:
class textblock
public:
const char& operator (std::size_t position) const //operator for const 物件
return text[position];
char& operator (std::size_t position) //operator for non-const物件
return text[position];
private:
std::string text;
textblock的operators可以這麼使用
textblock tb(「hello」);
std::cout << tb[0]; //呼叫non-const textblock::operator
const textblock ctb(「hello」);
std::cout<< ctb[0] ; //呼叫const textblock::operator
在日常運用中const物件大多用於passed by pointer-to-const 或 passed by-reference-to-const的傳遞結果
void print(const textblock & ctb) //此函式中ctb是const
std::cout<
std::coutstd::cout錯誤起因於對乙個「由const版之operator返回」的const char&施行賦值動作。
考慮以下的問題
class ctextblock
public:
char & operator(std::size position) const //bitwise const 宣告
private:
char *ptext;
這個class不適當的將operator宣告為const成員函式,而該函式卻返回乙個引用物件內部值。
請注意operator實現**並不修改物件值,但是假如遇到以下的情況:
const ctextblock cctb(「hello」);
char * p = cctb[0];
*p = 『j』; //實際上卻修改了cctb中的值 , 使其中的資料變成了jello
雖然建立了乙個常量物件並卻設為某值,而且只是修改了他呼叫const成員函式,但是還是修改了它的值。
在考慮以下的問題:
class ctextblock
public:
std::size_t length() const;
private:
char *ptext;
std::size_t textlength; //最近一次計算的文字長度
bool lengthisvalid; //目前的長度是否有效
std::size_t ctextblock::length() const
if(!lengthisvalid)
textlength = std::strlen(ptext); //錯誤,在const成員函式內部不能夠給textlength和lengthisvalid賦值
lengthisvalid = true;
return textlength;
這個問題的解決辦法如下:
將變數定義成變的,這樣就可以在常量函式內為其賦值。
具體**如下
class ctextblock
public:
std::size_t length() const;
private:
char *ptext;
mutablestd::size_t textlength; //最近一次計算的文字長度
mutable bool lengthisvalid; //目前的長度是否有效
std::size_t ctextblock::length() const
if(!lengthisvalid)
textlength = std::strlen(ptext); //錯誤,在const成員函式內部不能夠給textlength和lengthisvalid賦值
lengthisvalid = true;
return textlength;
關於C 中const的一些研究
最近複習的過程中發現網上對於const的說法不一,讓人摸不著頭腦,為了搞清其原理,決定通過反彙編的方式來看一看其內部究竟發生了什麼,下面是一篇簡單的介紹反彙編指令的文章,用來理解本次所研究的東西已經足夠 下面將按照乙個觀點乙個例子的方式來進行 該測試基於vs2017環境 1.將字面值賦給const變...
關於C 的一些細節 一
一.概述 b.s.真正的程式設計需要比純粹的原理更重要 資料 演算法 程式 通用程式設計 gp強調演算法 oop強調資料 可移植性和標準 將依賴於硬體的部分放在函式模組中.二.c 程式設計 1.關於標頭檔案 iostream 新編譯器 使用 include using namespace std 老...
C 一些細節
include include pthread.h using namespace std static pthread mutex t mutex class single class single public static single instance static single getin...