对于const修饰符的总结

1.const和变量

例如:
const int a = 10;
这将使得a的值为一个常量,后面无法改变,需要注意 使用const修饰的变量必须被初始化const int a;
这样的代码会使得编译失败。

2.const和引用

int a = 10;
const int &b = a; 

使用const修饰的引用将无法改变引用对象的值,即类似

b = 5;

这样的代码会使得编译失败。
所以这样的引用方式常常可以用在函数形参中,来保证函数内部只能对对象进行“读”操作而无法进行“写”操作。举个例子

inline int max(const int &a,const int &b)
{
return a<b?b:a;
}

上述代码是正确的,只对被引用的对象进行“读”操作。

inline voidswap(const int &a,const int &b)
{
	a ^= b;
	b ^= a;
	a ^= b;
}

上述代码会使得编译失败,因为尝试改变被const修饰的引用对象的值。

3.const 和 指针

最常见的例子,

int a = 10;
int *const p1 = &a;
const int *p2 = &a;

分别阐述两个const的作用,
讲讲区分方式:从右往左读,第一个const修饰的是p1,
第二个const修饰的是 整个(int *p2)。
第一个const的作用:修饰p,表示指针p1的值本身是一个常量,无法被改变,即类似

int b = 20;
p1 = &b;

这样的代码是错误的,因为p1被const修饰后,值无法改变。但是

*p1 = 15;

这行代码没有错。

第二个const的作用:修饰整个(int * p2),表示p2指针指向的对象的值无法被改变,是一个指向常量的指针,即

*p2 = 15;

这行代码是错误的,但是

int b = 20;
p2 = &b;

这样的代码没有错

4.顶层const 和 底层const

所谓顶层const 是指 变量本身的值不可变,那这个const就是一个顶层const
底层const值 指针变量指向的对象不可变,那这个const为一个底层const

int a = 10;
int *const p1 = &a;//这个是底层const
const int *p2 = &a;//这个是顶层const

5.constexpr

constexpr也是一个修饰符,用于表示要修饰的变量变成一个常量表达式
constexpr int a = 10; 这样的常量表达式需要满足的要求是程序在编译过程就可以 get到这个变量的值,而不是在运行阶段才能get到。例如

srand(time(0));
constexpr int a = rand();

就会使得编译失败,因为rand函数在运行阶段才能获得返回值,a才能被初始化。

比较下面两行代码

int a = 10;
constxpr int *p1 = &a;
const int *p2 = &a;

这两行代码看起来类似,但是事实上p1和p2的类型是不同的。
从上文的描述中可以获知得const int *p2 = &a;中的const是一个底层const,表示指向的对象的值无法被改变,是一个指向常量的指针。
constxpr int *p1 = &a;则表示 p1 本身 是一个常量,无法改变,也就相当于一个 顶层const。

6.const 和 类的成员函数

可以在类中成员函数声明的最后加上const修饰符,作用是使得该成员函数 无法对类中的对象的值进行改变。

template<typename T>
class stack{
private:
std::vector<T> elems;
public:
pop();
push();
top()const;
bool empty()const;
}

如上面的例子中,这是一个stack类数据结构的声明,其中成员函数 pop 和 push 的作用是往栈中添加、删除元素,这就会对类中的elems对象就行改变,所以没有用const修饰;而top函数和empty函数只是简单的返回头元素 和 判断是否为空,并没有对对象进行改变,所以加了const修饰。

7. const 和 define宏定义

1)const定义的常量有类型,#define定义的没有类型。
编译时可以对前者进行类型安全检查,而后者仅仅是简单的文本替换。

2)const定义的常量在编译时分配内存,只展开一次。
#define定义的常量是在预编译时进行替换,不分配内存,但是在编译过程中会多次展开,浪费资源。

3)作用域不同,const定义的作用域为该变量的作用域范围。而#define定义的常量
作用域为它的点到程序结束,当然也可以在某个地方用#undef取消。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值