1、用const
修饰函数的参数
-
参数是值传递
由于函数将自动产生临时变量复制该参数,该参数无需保护,没必要用
const
-
参数是指针传递或者引用传递
const
修饰的指针或引用所指向的值不可变。如果该参数只是起“被读取”的作用,最好用const
修饰保护。
对于复合数据类型,最好使用引用传递,因为值传递的过程中要进行临时对象的构造,复制,析构,这些都会造成时间和空间的浪费。
class list {
string name;
public:
void show(const list& l) {
cout << name;
}
}
2、用const
修饰函数的返回值
如果函数的返回值用const
修饰,接受这个返回值的变量也只能用const
修饰。
const int sum(int a, int b) {return a+b;}
int s = sum(1,1); //error
const s = sum(1,1); //编译通过
3、const
成员函数
任何不会修改数据成员的函数都应该声明为const
类型。如果在编写const
成员函数时,不慎修改了数据成员,或者调用了其它非const
成员函数,编译器将指出错误,这无疑会提高程序的健壮性。
class list {
string name;
public:
void show(list& l) const {
cout << name;
}
}
4 、const
对象
const
修饰的对象只能访问const
函数和const
成员变量
class list {
string name;
public:
void show(list& l) const {
cout << name;
}
void show2(list& l) {
cout << name;
}
}
const list l;
l.show2(); //error
l.show(); //编译通过
5 、与constexpr
区别
-
对于修饰Object来说
const
并未区分出编译期常量(编译时就可以确定的常量表达式)和运行期常量constexpr
限定在编译期常量,也就是说,编译器看见constexpr
就可以放心的对常量进行编译期的优化了。
-
对于修饰函数来说
-
constexpr
修饰的函数,返回值不一定是编译期常量#include <iostream> #include <array> using namespace std; constexpr int foo(int i) { return i + 5; } int main() { int i = 10; std::array<int, foo(5)> arr; // OK foo(i); // Call is Ok // But... std::array<int, foo(i)> arr1; // Error }
-
所以,对于constexpr
需要两方面看待。
constexpr
修饰的函数,简单的来说,如果其传入的参数可以在编译时期计算出来,那么这个函数就会产生编译时期的值。但是,传入的参数如果不能在编译时期计算出来,那么constexpr
修饰的函数就和普通函数一样了。不过,我们不必因此而写两个版本,所以如果函数体适用于constexpr
函数的条件,可以尽量加上constexpr
。
而检测constexpr
函数是否产生编译时期值的方法很简单,就是利用std::array需要编译期常值才能编译通过的小技巧。这样的话,即可检测你所写的函数是否真的产生编译期常值了。
6、指向常量的指针(pointer to const)、常量指针指针(const pointer) 与 constexpr指针
-
指向常量的指针,又叫底层指针
-
作用:不能通过指针修改值,无论指向的值是否是const, 指针本身可以改变指向。
int a =1; const int b = 1; const int* p; p = &a; *p = 2;//错误 p = &b; *p = 2; //错误
-
-
常量指针,又叫顶层指针
-
作用:不能修改指针的指向,指针本身是常量,所以必须在声明时初始化。
int a = 1; int b = 1; int* const p = &a; p = &b; //报错
-
-
constexpr指针
- 作用和常量指针(顶层指针)一样
6.5、类型别名与常量指针
typedef int* ip;
int a = 1;
const ip p; //等价于 int* const p; 也就是顶层指针,顶层指针必须初始化,所以这句是会报错的
const ip p = &a; //正确
7、const引用
int const& a;
和 const int& a;
作用一样,可以不加区分。
参考:https://www.zhihu.com/question/35614219/answer/63798713
https://www.jianshu.com/p/34a2a79ea947
《C++ primer》2.4节