const
概念
const允许我们指定一个语义约束,编译器会强制执行这个约束,告诉编译器和其他程序员某值不应该被改变,当某个值确定不可被改变时,我们就应该使用const
使用场景
- 修饰变量:限定变量不可修改
- 修饰指针:指针常量和常量指针
- 修饰函数
- const int& fun(int& a); //修饰返回值
- int& fun(const int& a); //修饰形参
- int& fun(int& a) const{} //const成员函数
- 类
- 修饰成员变量:类的数据成员不能在任何函数中被赋值或修改,但必须在类的构造函数中使用初始化列表的方式进行初始化。类可以创建多个对象,不同的对象其const成员变量的值是不同的。
- 修饰成员函数:
- 防止成员函数修改成员变量的值,即该成员函数并不能修改成员变量。而非const对象可以访问任意的成员函数,包括const成员函数;
- const成员函数不可以修改对象的数据,不管对象是否具有const性质。
- 修饰类对象:const修饰的类对象,该对象内的任何成员变量都不能被修改,只能调用const成员函数。
举例
operator*声明式:
class Rational {...};const Rational operator*(const Rational& lhs, const Rational& rhs);
Rational a, b, c;
(a * b) = c;
if (a * b = c) ...
本意可能是判断 a*b 和 c 是否相等,如果不加const,写成=的情况下,会导致错误。
拓展
拓展1:const修饰的成员函数可以修改mutable修饰的成员变量
拓展2:const和non-const成员函数的有着实质等价的实现时,可以在non-const函数中调用const版本的函数
class TextBlock{
public:
...
const char& operator[](std::size_t position) const
{
...
return text[position];
}
char& operator[](std::size_t position)
{
return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]);
}
...
};
- 第一次类型转换为*this添加const,先将*this从原始类型 TextBlock& 转换为 const TextBlock& 类型
- 第二次从返回值中移除const属性
拓展3:static和const可以同时修饰成员函数吗?
不可以。C++编译器在实现const的成员函数的时候会在函数中添加一个隐式的参数const this*。但当一个成员为static的时候,该函数是没有this指针的。也就是说此时const的用法和static是冲突的。两者的语意是矛盾的。static的作用是表示该函数只作用在类型的静态变量上,与类的实例没有关系;而const的作用是确保函数不能修改类的实例的状态,与类型的静态变量没有关系。因此不能同时用它们。
static
- 静态成员变量:类的所有对象间共享的成员变量,不属于某个类对象,而属于类本身,静态成员变量在所有类之间只有一个实例。static成员必须在类外进行初始化,而不能在构造函数内进行初始化。不过也可以用const修饰static数据成员在类内初始化 。
- 静态成员函数:用static修饰成员函数,使这个类只存在这一份函数,所有对象共享该函数,不含this指针。静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问。不可以同时用const和static修饰成员函数。
- 静态局部变量:静态局部变量在程序运行期间只初始化一次,一般用于单例模式
- 内存中的位置:data段
- 作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束。
- 静态全局变量:
- 内存中的位置:静态存储区
- 初始化:未经初始化的全局静态变量会被程序自动初始化为0
- 作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。(只能在本文件中存在和使用)
全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的(在其他源文件中使用时加上extern关键字重新声明即可)。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。
- 普通函数:修饰普通函数,表明函数的作用范围,仅在定义该函数的文件内才能使用。在多人开发项目时,为了防止与他人命名空间里的函数重名,可以将函数定位为 static。
324



被折叠的 条评论
为什么被折叠?



