2020年5月4日 下午5:33
注:本文主要参考《C++ Primer》
总结:
- 我认为要区分这三个定义变量、函数、甚至是类中的使用方法,关键还是要站在需求的角度,千万别背,背会了也不会用。C++的设计者当初也是为了满足用户的需求在后期加上的这些功能,并且通过关键字的方式开放给程序员。
讲解static const的文章
c - Const vs Static Const - Stack Overflow
c - What is the difference between static const and const? - Stack Overflow
- Addendum: Note that the behavior is different in C++. In C++, a const variable has internal linkage by default, so static const is redundant and extern const is necessary to get a constant with external linkage.
六个关键性的思考角度、概念:
- 名字作用域,对象声明周期 -> P184
- 编译,运行 -> P58
- 声明,定义 -> P41
- 有一个问题,为什么C++要设计六个概念?或者扩大点说,语言为什么要设计这些概念?
- 名字作用域,对象声明周期:域、周期都是表示的是范围的意思,在语言中加入范围的感念,可以有效的区分我们不再需要的定义、值,就像是标签一样,我们就可以将抛弃掉,有效的节省内存的使用
- 编译,运行 :关键是这里的编译,这其中就需要涉及到类型这个概念,动态类型语言不需要编译,静态类型需要需要编译(因为编译才定义成了静态类型语言),语言有了类型可以很好的帮助人类进行抽象,也可以进行进行类型的检查,将问题提前锁定在编译器更加安全
- 声明,定义:是C++为了运行程序拆分成多个逻辑部分来编写,所以支持了分离式编译,该机制允许将程序分割为若干的文件,每个文件可被单独编译。因此,C++将声明定义分开,这样就可以做到文件间共享代码的方法
- 声明:使得名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明
- 定义:负责创建于名字关联的实体
Static:全局变量 函数中 类中
- 全局变量:生命周期知道程序结束,作用域仅限于当前源文件
- 函数:P184局部对象->P43名字作用域,对象生命周期
- 自动对象->P40 默认初始化
- 局部静态对象
- 类:P269 类的静态成员
- 声明静态成员
- 使用类的静态成员
- 定义静态成员
- 静态成员的类内初始化
- 静态成员能用于某些场景,而普通成员不行
Constexpr:
- P58 constexpr常量表达式
- 常量表达式
- constexpr变量
- 字面值类型
- 指针和constexpr
- 函数中:P214
- constexpr函数
- 把内联函数和constexpr函数放在头文件内
- 类中:P267 字面值常量类
- constexpr构造函数
Const :
- static和const关键字的作用_JavaScript_许政的博客-CSDN博客
- 欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了
- 对指针来说
- 可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const
- 在一个函数声明中
- const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值
- 对于类的成员函数
- 若指定其为const类型,则表明其是一个常函数,不能修改类的 成员变量
- 对于类的成员函数
- 有时候必须指定其返回值为const类型,以使得其返回值不为“左值”
1
2
3const classA operator*(const classA& a1,const classA& a2); //operator*的返回结果必须是一个const对象
classA a, b, c;//如果不是,这样的变态代码也不会编译出错
(a * b) = c; // 对a*b的结果赋值,显然不符合编程者的初衷,也没有任何意义
- 有时候必须指定其返回值为const类型,以使得其返回值不为“左值”
- 与constexpr的区别:
- constexpr的语义是:值在编译期就确定,并且在运行期不会改变。
- const指的是运行期:
- const变量的值可以在运行期再确定,编译器可以不确定,const保证的是运行期的不能改变变量的值,否则会报错
- 总结,constexpr和const最大的区别:值最晚什么时候确定,给的下限;并没有规定上限。
- const: |——————编译期———————|—————运行期———————|
- constexpr: |——————编译期———————|
- 上面表示的是值必须在指定区间中确定,否则出错
- eg:P58
- 使用const的常量表达式
1
2
3
4
5
6
7
8
9// 常量表达式
const int max_files = 20;//max_files是常量表达式
const int limit = max_files + 1;//limit是常量表达式
// 非常量表达式
int staff_size = 27;//staff不是常量表达式
const int sz = get_size();//sz不是常量表达式
/*
1.尽管staff_size的初始值是一个字面常量,但是由于他的数据类型只是普通的int而非const int,所以他不属于常量表达式
2.尽管sz本身是一个常量,但是他的具体值知道运行时才能或得到,所以也不是常量表达式 - 使用constexpr的常量表达式
1
2
3
4// constexpr类型以便编译器来验证变量的值是否是一个常量表达式
constexpr int mf = 20;//20是常量表达式
constexpr int limit = mf + 1;//mf + 1是常量表达式
constexpr int sz = size();//只有size是一个constexpr函数时,才是一条正确的声明语句
- 使用const的常量表达式