一、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类型的转换,在以后的文章里在叙述。