【c++】——const详解
文章目录
- 1、在.c中const 的用法
- 2、在.cpp中const 的用法
- 3、Const和static修饰的成员
- 3.1const修改成员变量的处理
- 3.2static修饰的成员变量
- 4、int* const p和const int* p区别
首先,我们要来明确一下,什么是const,在我们通常的观念里面,我们会认为下面这个代码是错误的。
const int b = 20;b = 30;
因为const修饰的变量不能作为左值。初始化完成后值不能被修改。
1、在.c中const 的用法
在我之前的一篇博文中,有对其大概的讲解,c语言中const的用法
1.1const修饰的量,可以不用初始化
例如以下的程序是错误的:
const int a;
a = 20;
因为const的值虽然可以不用初始化,但是以后就不能作为左值来进行修改了。
所以一般情况下还是对其进行初始化。
1.2const修饰的量不叫常量,叫常变量
他和变量的唯一区别就是不能够把她作为左值修改。比如下列程序就是错误的。
const int a = 20;
int array[a] = {};
1.3练习
下列.c程序,打印结果是多少?
int main()
{const int a = 20;int* p = (int*)&a;*p = 30;printf("%d %d %d\n", a, *p, *(&a));return 0;
}

指针指向的是a的内存。结果是30,30,30.因为a这块内存已经被改了。a一直都是一个变量
2、在.cpp中const 的用法
2.1const修饰的量叫做常量,必须初始化
所以以下代码则是正确的:
const int a = 20;
int array[a] = {};
2.2const修饰的量叫常量
还是上述.c里面练习的代码。打印结果则为20 30 20
这是因为const的编译方式不同
- c中,const就是当做一个变量来编译生成指令的
- c++中所有出现const常量名字的地方,都被常量的初始值替换了。尽管后期可能对其做了很多处理还是不能改变常量的值。
2.3常量值不允许被修改(这种修改包括间接修改和直接修改)
1、对于间接修改的错误示范
【栗子1】
int main()
{const int a = 10;int*p =&a;return 0;
}
在以上代码中,第二句就会报错。因为如果此时允许普通的指针指向常量内存块,以后我们要进行*p =20的操作就不对了,因为常量值不允许间接访问来修改。主要是杜绝间接访问常量内存的风险
【栗子2】
int main()
{const int a = 10;const int*p =&a;int *q = p;return 0;
}
- 在我们之前c语言的理解方式当中,会认为第三句的转换方式涉及到
const int*到int*的转换,相当于把权限扩大了,所以不对 - 但是以c++的方式来理解,在第二句代码中const修饰的是
*p,后面指向p的指针q就存在间接访问修改*p的风险。
2、对于间接修改的正确示范
【栗子1】
int main()
{int a = 10;int*p =&a;const int *q = p;return 0;
}
因为我们只从const修饰的量往下看有没有风险存在,const修饰的是*q,其间接访问就是*q有const修饰,所以没有风险存在
【栗子2】
int main()
{int a = 10;int* const p =&a;int *q = p;return 0;
}
因为const修饰的是p,p就是直接访问,这时,如果要间接访问必须就要二级以上的指针来访问,所以不存在间接访问,没有风险
3、Const和static修饰的成员
关于成员变量之前的关系,可以参考博文成员方法之间的关系
3.1const修改成员变量的处理
1、常对象不能调用普通方法
为了说清楚这个结论,我们引用一段错误的代码来加以分析。
class Test
{public: Test(int a):ma(a){}void show(){}private:int ma;};
int main()
{const Test test(10);test.show();return 0;
}
仔细分析这段代码
- 首先生成了test这个常对象,调用show成员方法。
- 因为在方法内部的this方法为
Test* const this,const修饰的是this指针不是*this,代表我们可以通过*this的方式来修改常量的值。这样显然是不允许的
上面的这段类里面的代码就和const对常量操作的下述代码逻辑相同。
const int a= 10;
int* const p = &a;
显然是不可以的。这个问题的解决方法就是让this指针变为const Test* const this的方式,也就是把show成员方法变为常方法
2、普通函数可以调用常方法
想要得到其理论的正确性,我们先在常量里面进行分析,普通函数调用常方法类比到变量里面的逻辑代码如下:
int a =10;
const it* const p = &a;
显然这样的表达式是正确的,类比到类里面也就是正确的。
3、常方法不能调用普通方法
基于上面两条理解一下,其实常方法里面的this指针指向的对象就是常对象,在调用print方法的时候就变成了用常对象来调用普通方法,显然这样是不行的。
4、在普通方法里面可以调用常方法
总结
- 常对象不能调用普通方法,常对象只能调用常方法
- 普通对象可以调用常方法
- 常方法中不能调用普通成员方法
- 普通成员方法中能调用常方法。

3.2static修饰的成员变量
首先我们写一个静态成员变量的例子,如下代码所示:
class Test
{public:Test(int b):mb(b){}void show(){std::cout<<"ma: "<
其中ma为静态成员变量,他主要有以下特点:
-
所属关系:成员变量不属于对象,属于类。是所有对象共享的 -
初始化方式:构造函数不能初始化静态的成员变量,一定要在类外初始化。
【解释】因为构造函数是初始化对象所占的内存空间的,静态成员变量都不属于对象。所以在类外进行初始化的操作如下:

-
静态成员变量的访问:通过对象或者作用域的方式都可以。具体操作如下:

而对于静态成员方法的访问是不依赖于对象的访问,只能用作用域的方式来访问静态成员方法。

-
静态成员方法的访问权限:因为静态成员方法是_cdecl调用约定,也就是说没有this指针的,所以不能访问普通的成员变量,可以访问全局变量和静态成员变量。 -
调用关系:静态成员方法不可以调用普通成员方法,但是反过来普通成员方法就可以调用静态成员方法。因为普通函数的调用是通过this指针来调动的
4、int* const p和const int* p区别
const和一级指针结合的三种情况
在c++ 的语言规范里面,我们都知道const修饰的是离他最近的类型。
情况一:
const int *p;
const修饰的是*p,表示的是可以任意指向不同int 类型的内存,但是不能通过指针间接修改指向的内存的值
所以,*p = 20错误的 p = &b正确的
情况二:
int* const p;
表示的是这个指针p现在是常量,不能再指向其他内存,但是可以通过指针解引用修改指向的内存的值
所以, *p = 20正确的 p = &b错误的
情况三:
const int *const p;
这种情况下,不仅仅指针p是常量,指针所指向内存里面存放的值也是常量,都不允许修改。
总结:
- const int *p这个const修饰的是p指向的内存的值不能被修改,但是p本身是可以修改的
- int* const p这个const修饰的是p本身是个常量,不能被修改,但是p指向的内存的值是可以被修改的。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
