【c++】const

零、前言

关于const,目前让我对这个知识点分类,我会分为:c语言中的const;c++中的const、c++中类的成员函数的const

一、C语言中的const

1.c语言中,const修饰的是常变量;常变量只有一个特点:不可以做左值。也就是不可以放在等号左边。想了一下,不做左值这是一条语法规则,在编译时期检查出,所以但凡放在=左,编译器就会报错。如图:

其他特性和普通变量一样。所以,c语言中的conse修饰的变量,是可以被改变的。

代码如上图:并且我将文件名改为.c,这是一个简单的c文件

#include<stdio.h>

int main()
{
	const int a = 10;    //常变量a为10
	int *p = (int*)&a;   //取a的地址将其强转为int*  ,然后赋值给指针p
	*p = 20;             //改变p所指向的地址的值,也就是解引用改变a的值
	
	printf("a = %d\n",a); 
	printf("*p = %d\n",*p); 

	return 0;
 }

c语言中的强转真是一个暴力转换,能消除常性),将const int*  ->  int*  。这一点真是让我大吃一惊。

查看运行结果:

 发现a的值被改变。

二、c++中的const

1.对比c语言中的const

c++中const修饰的是常量。何为常量:就是不可以更改的。

有如下3个性质:

    1.常量要初始化(因为不可修改,所以没有初始值就没有意义)
    2.不能做左值
    3.不能间接修改,杜绝间接访问修改风险

但是,我们还是可以通过暴力手段,强行试着改变一下:还是上述代码,我将文件名后缀由.c改变为.cpp

 查看运行结果:

 结论:c++中,在用到常量的地方 替换成 该常量初始化的值。

在程序要打印a的时候,代码已经被替换成:printf("a = %d\n",10); 不由想起了宏替换。

说下我的理解,不是咱const不够牛逼,实在是这句强转int* p = (int*)&a; 太无赖了!道高一尺魔高一丈,强转是真够暴力,强转前需要深思。

2.const的几种使用辨析

在const修饰指针时,确实会有多种写法,写法不同产生的意义不同。之前c和c++的区别中,总结过笔记:

 再次强调:

我理解的const:修饰最近的一个已经成型的类型,修饰什么,什么不可改变。

例1:

const int * p = &a;

int const * p = &a;

这两句代码,const都修饰int,int是已经成型的类型,修饰int即就是这个值,所以p的指向可以改变,*p则不可以(*p可能带来修改的风险)。

例2:

int* const p = &a;

const修饰int* ,修饰指针,则p的指向不可以改变,但*p = 323;是可以的,所指向的值是可以改变的。

例3:二者都添加const

const int* const p = &a;

p的指向不可以改变 并且 p所指地址存放的值也不可以改变。

2.5 effective c++中是这样辨析const

下面几句代码的注释很有意思:

const pointer,const data:const即修饰指针也修饰数据

const data ,non-const pointer:const修饰数据,没修饰指针

看到effective c++中,和我说的“const修饰离它最近的已成型的类型”有差别,虽然说法不同,但结果相同。怎么理解,自己理解就好,不必过多纠结。

3.c、c++中const修饰的全局变量的区别:

c中:
const修饰的全局变量:属性为global
c++中:
const修饰的全局变量:属性为local即本文本可见   外部访问需加extern 

4.const修饰class中的成员函数 以及 自定义类的常对象

(1)常对象:里的成员变量都具有常属性。

(2)常对象不能访问普通函数,只能访问const修饰的成员函数。

   因为对象调用函数(或者说函数依赖于对象调用),类的成员函数如何知道它被哪一个对象调用呢?答曰:this指针

   对象调用成员函数时,默认第一个参数是this指针,this指针指向对象的地址;this指针的类型为:classname* const this;

    也就是说this指针是加了const属性的,const只是修饰的指针的指向,指向不可以改变,但是所指的内容是可以改变的。

但是,常对象的this指针的类型为:const classname* const this ,const即修饰指向也修饰所指的内容。

现有如下代码:

class Test
{
public:
	Test(int a) :ma(a){}
	void Show()//const //const Test* const this = &test; //Test* const ==> const Test* const
	{
		std::cout << "ma:" << ma << std::endl;
	}
public:
	int ma;
};
int main()
{
	const Test test(20);
	test.Show();
	return 0;
}

   对象test的地址:&test = const Test* const this,show函数中的this指针类型为:Test* const this

现在要将一个级别高(const修饰权限高)的指针赋值给一个权限低的,降低权限,就相当于低权限指针修改了高权限的值,那必然是不对的。

所以,const常对象不能访问普通函数,只能访问const成员函数。

5.const修饰迭代器

迭代器在某种角度上可以当做指针看待,这样的话就可以用const修饰,即const iterator it,但迭代器中还有一个const_itreator的类型(迭代器所指数据博客改变),二者就有差别了。

 第一次看很晕,不过后来再理解,很容易:

const iterator iter;//const修饰指向 

const_iterator iter;  //iter所指之物是const

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值