一、const對象的定義
const std::string hi = "hello!";
PS:const對象定義時必須初始化。可以用字面值常量初始化,也可以用同類型的變量初始化,若該變量沒有被賦值,則const對象存儲的是一個未知內存。
與其他變量不同的是,除非特別說明,在全局作用域中聲明的const變量是定義該對象的文件的局部變量,而非const變量默認爲extern。
二、const迭代器
1、const_iterator
該類型自身的值可以改變(即可以改變指向的地址),但不能用它來改變其所指向的元素的值,但並不是指該元素的值不能改變,因此,完全可以用非const變量初始化該迭代器。可以理解爲:自以爲指向const對象的迭代器。
vector<int>::const_iterator;//指向地址可以改變,但不能用它來修改指向的值
2、const迭代器
該迭代器的值一經初始化,便不能更改它的指向,而只能用它來改寫其指向的元素的值,因此用途不大。
const vector<int>::iterator;//指向的地址不能改變,但可以修該指向地址的值
三、指針與const
1、指向const對象的指針
可以在定義時不進行初始化:
constdouble *cptr;//可以改變指向的地址,但不能通過該指針修該指向對象的
//但該對象不一定不能通過其他方法修改,因此允許把非const對象的地址賦給指向const對象的指針
因此該類指針也可以理解爲:自以爲指向const的指針。
對此指針賦值時等號右端只能是變量的取地址形式,而不能是字面值常量。
在實際的程序中,該類指針通常用作函數的形參,將形參定義爲指向const的指針,可以確保傳遞給函數的實際對象在函數中不因爲形參而被修該。
2、const指針
該指針本身的值不能修改,但可以通過它修改它指向的值。
int errNumb = 0;
int *const curErr = &errNumb;//該語句定義的是指向int的const指針
//只能用int型變量初始化
與任何const量一樣,const指針也必須在定義時初始化。
3、指向const對象的const指針
不一定非要用const對象初始化。此類指針既不能修改指針的值也不能修該指針指向的值,因此也必須在定義時初始化。
constdouble pi = 3.14159;
constdouble *const pi_ptr = &pi;
4、指針、typedef與const
const限定符既可以放在類型前也可以放在類型後:
string const s1;
const string s2;
上式中,兩個語句是相同的,都是定義了兩個常字符串。
用typedef時:
string s;
typedef string *pstring;
const pstring cstr1 = &s;
pstring const cstr2 = &s;
string *const cstr3 = &s;
以上03、04、05三式都是定義的指向string對象的const指針。
將const限定符加在類型名前面很容易引起對所定義的真正類型的誤解。
四、const形參
在調用函數時,如果該函數使用非引用的非const形參,則既可給該函數傳遞const實參也可以傳遞非const形參。
如果將形參定義爲非引用的const類型,則在函數中,不可以改變實參的局部副本,也僅僅如此。C++中,具有const形參或非const形參的函數並無區別,這是對C語言的兼容。因此有下文的重載與const形參。
五、重載與const形參
僅當形參是引用或指針時,形參是否爲const纔有影響。
可以基於函數的引用是指向const對象還是非const對象,實現函數重載。
當形參以副本傳遞時,不能基於形參是否爲const來實現重載。
PS:const*與*可以重載,而*const與*不可以重載。
六、const引用
利用const引用可以避免複製,減少內存開銷。
如果使用引用形參的唯一目的是避免複製實參,則應該將形參定義爲const應用。
七、const成員函數、
const修飾符可以將類的成員函數定義爲常量成員函數,用以避免對象的數據成員被函數修改。
conat對象、指向const對象的指針或引用只能用於調用其const成員函數,如果嘗試用它們來調用非const成員函數,則是錯誤的。
至於const類型與非const類型的轉換,在以後的文章裏在敘述。