• 150632

    文章

  • 1244

    评论

  • 13

    友链

  • 最近新加了换肤功能,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

const与static和内存模型


1.const

  • C语言——在C语言中,const只能限定变量,使变量中的内容无法被修改,但是此时变量依旧是变量,而不是常量,因为可以通过T*指针拿到变量的地址而不需要进行类型强制转换,并且可以通过指针修改该变量中的值。
  • C++——(1)限定变量,C++中的const修饰变量的话,会使变量成为常量且具有类似于宏常量的作用,被const修饰的变量会在编译期间就被替换数值,而不是运行阶段。如以下代码,会输入10    1。    (2)限定类数据成员。修饰类的数据成员标识该数据成员为常量无法修改,由于被const修饰的常量必须在定义时初始化,因此具有const类型数据成员的类必须显示定义构造函数且必须在初始化列表中进行初始化。     (3)限定类成员函数。修饰类数据成员意味着修改隐藏的this指针,使this指针指向的内容无法修改。因此const成员函数不能修改任何非静态数据成员(使用mutable修饰成员变量,可以在const函数中修改成员的值)。且静态成员函数不允许使用const进行限定,原因在于静态成员函数没有this指针。const函数不能调用其他非const函数,但是非const函数可以调用const函数。(4)限定类对象。const对象不能调用非const成员函数,但是非const对象可以调用const成员函数。    小结:关于const函数const对象与普通函数,对象之间的互相调用问题,我认为主要原因在于就像const int*无法直接给int*赋值,简单来说就是,我是个const类型,本来我的内容是不能修改的,现在我要把我的地址给你,你又是可以修改的类型,那不就乱套了。但是反过来就不一样,我本就是可以修改的,然后把我的地址给一个不能修改内容的类型,是无所谓的,不管你改不改我的内容都可以。
  • 再谈const——const在限定全局变量时,会把全局变量的链接性改为内部链接,这样做的目的是为了方便程序员。试想假如在一个头文件中定义了一组常量,并在同一个程序的多个文件中包含该头文件,就会由于全局变量的外部链接性导致违背单定义规则,此时只能将其他const常量添加修饰符extern,但是添加了extern后只能有一个文件进行初始化,其他文件不能对同一个全局变量进行初始化,而const又必须在定义时进行初始化,这是无法解决的,所以在使用const限定全局变量时,将全局变量的链接性改为内部是必须的。这样不同的文件都能使用自己的一份常量而不冲突。
  • volatile——volatile与const同属于限定符,被称为cv限定符,此关键词表明,即使程序没有对内存单元进行修改,其值也可能发生变化。可能是指针被指向了一个硬件,硬件修改了内存单元的内容,或者两个程序互相影响,使用了同一个内存单元。该关键词的作用是改善编译器的优化能力。例如,假如编译器发现程序在几条语句中两次使用了某个变量,则编译器可能不是让程序查找这个值两次,而是将这个值缓存到寄存器中。这种优化假设了变量不会在这两次使用之间变化。使用volatile相当于告诉编译器不要进行这种优化。
const int a = 1;
	int* p = (int*)&a;
	*p = 10;
	cout << *(int*)&a << endl << a;

 

2.static和内存模型

  • 存储持续性——C++依据存储持续性将数据存储方式分为三种(在C++11中新添加了一种),何为存储持续性:简单来说就是数据存储在内存中的存在时间。(1)自动存储持续性:即在函数定义中声明的变量为自动变量,它的存储持续性为自动的,即在代码块被运行时创建变量,在代码块结束运行时被自动释放。(2)静态存储持续性:定义在函数体外(全局变量)或者被static修饰的变量的存储持续性都为静态。它们在程序运行的整个过程中都存在。(3)动态存储持续性:被new创建的变量的存储持续性为动态的,这种分配的内存将一直存在,直到被delete释放或者程序结束。(4)线程存储持续性(C++11):如果变量是使用关键字thread_local声明的,则其生命周期与所属线程一样长。
  • 作用域和链接——作用域描述了名称在文件的多大范围内可见。链接性描述了名称如何在不同文件间共享。链接性为外部的名称在各文件中共享,链接性为内部的名称只能被处于同一个文件中的函数共享。自动变量不具有链接性,因为它们不能被共享,只能被一个函数使用。C++函数的作用域可以是整个类或者整个文件,但不能是局部的,因为不能再函数中定义函数。不同的C++存储方式是通过存储持续性,作用域,链接性来描述的。
  • static——(1)static修饰自动存储性变量:即使用static修饰局部变量,会修改局部变量的存储持续性,使之在程序运行的整个过程都存在,且在函数调用时只会被初始化一次。(2)static修饰全局变量:全局变量本身具有外部链接性,被static修饰以后会改为内部链接性,即该变量会只在本文件中可见,因此如果同一个程序的其他文件定义了一个全局变量,如果想在本文件中也定义一个同名全局变量而不是通过extern引用,则可以使用static,可以做到数据隐藏。(3)static不修饰全局变量——此时全局变量具有外部链接性,由于单定义规则,同程序的其他文件不能再定义同名变量,只能使用extern进行引用且不能初始化,只能有一个文件进行初始化。(4)static修饰普通函数——函数的作用域绝对不会是局部的,因此函数的链接性是外部的,因此不能在同程序的不同文件定义多个同名函数,同样使用static可以达到同名隐藏的目的。(5)static修饰类数据成员:static修饰类数据成员的话,意味着此成员存储在静态区而不是对象中,因此不能在构造函数中对其进行初始化,它不属于对象的成员,只能在类外进行初始化。(6)static修饰类成员函数:被static修饰的成员函数不具有this指针。因为它不属于对象,对象可以调用静态成员函数,但是不会传递this指针。因此静态成员函数不能调用非静态成员函数,因为无法给其传递this指针,但是非静态成员函数可以调用静态成员函数,同理,静态成员函数不能被const修饰,因为没有this指针,不能是虚函数。    小结:无论是静态数据成员还是静态成员函数都可以通过类型加作用域符号的方式调用,也可以通过对象调用。

 


695856371Web网页设计师②群 | 喜欢本站的朋友可以收藏本站,或者加入我们大家一起来交流技术!

0条评论

Loading...


发表评论

电子邮件地址不会被公开。 必填项已用*标注

自定义皮肤 主体内容背景
打开支付宝扫码付款购买视频教程
遇到问题联系客服QQ:419400980
注册梁钟霖个人博客