首页 > 其他分享 >static和const

static和const

时间:2023-07-23 17:56:31浏览次数:42  
标签:const 函数 静态 成员 static 变量

static

static修饰的变量存储于全局区,而初始化的和未初始化的在全局区分开储存,如果没显示初始化会被程序自动初始化为0

对于局部变量

  • static延长了它的生命周期,即不随函数的销毁而销毁,只有程序运行结束才会销毁
  • static使得局部变量只在第一次调用的时候初始化,之后的调用不再初始化,不运行初始化代码
  • static修饰的局部变量具有记忆性可以将上次的调用结果保存下来作为下次调用的初值
  • static相比于全局变量的好处在于,由于它没有改变作用域,因此只能在函数内使用,受函数控制维护起来方便

对于全局变量

  • static改变的是它的作用域,即只能在本文件中使用,不能被外部文件进行extern声明并使用,想要在外部使用必须在外部文件中包含static全局变量定义的文件的文件名,这相当于将该文件的所有内容在外部文件中重新写了一遍
  • static修饰的全局变量作用在于防止各文件定义同名的全局变量,而导致名称冲突

对于函数

它和全局变量一样

补充知识

 

1.栈区:由编译器自动分配释放,像局部变量,函数形参,都是在栈区。会随着作用于退出而释放空间。

 

2.堆区:程序员分配并释放的区域,像malloc(c),new(c++)

 

3.全局数据区(静态区):全局变量与静态变量的存储是放在一起的,初始化的全局变量与静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,程序结束释放。

 

4.代码区

 

C++的static

以上是C的static,C++的static在C的基础上增添了关于类的用法

static修饰的成员变量

其实与其说增添了关于类的用法还不如说对类使用static修饰的局部变量的属性

  • 首先,static修饰的成员属性(叫做静态成员变量)存储在全局区,这就意味着它不占用类的内存空间,这就意味着静态成员函数不能在类声明中定义;静态全局变量只有一份,所有实例化的对象共享这个静态全局变量,因此静态成员变量也称为类变量,这使得我们不仅可以用普通成员变量的访问方式访问还可以使用Rectangle::s_sum的形式访问。
  • 静态成员变量不随实例化的对象销毁而销毁,只有程序运行结束才会销毁。
  • 静态成员变量只在实例化第一个对象的时候初始化,之后不再初始化,不运行初始化代码
  • 静态成员变量具有记忆性,可以将上次实例化对象时赋予静态变量的结果保存下来,作为下次实例化对象的初值

由此可见C++对于static的使用和C语言对于static在局部变量的使用是一模一样,只不过函数替换成了实例化对象,又增添了一些类的东西

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Rectangle
 5 {
 6 private:
 7     int m_w, m_h;
 8     static int s_sum;
 9 
10 public:
11     Rectangle(int w, int h)
12     {
13         this->m_w = w;
14         this->m_h = h;
15         s_sum += (this->m_w * this->m_h);
16     }
17 
18 
19     void GetSum()
20     {
21         cout << "sum = " << s_sum << endl;
22     }
23 
24 
25 };
26 
27 int Rectangle::s_sum = 0;  //初始化
28 void test01()
29 {
30     Rectangle rect1(3, 4);
31     rect1.GetSum();
32     cout << "sizeof(rect1)=" << sizeof(rect1) << endl;
33 }
34 
35 int main()
36 {
37     cout << "sizeof(Rectangle)=" << sizeof(Rectangle) << endl;
38     test01();
39     Rectangle rect2(2, 3);
40     rect2.GetSum();
41     cout << "sizeof(rect2)=" << sizeof(rect2) << endl;
42 
43     system("pause");
44     return 0;
45 }

 

所有的大小等于8意味着:

静态成员变量不占用类的内存空间,且只有一份

18=12+6意味着

  • 静态成员变量不随实例化的对象销毁而销毁(test01函数结束后rect1被销毁),只有程序运行结束才会销毁
  • 静态成员变量只在实例化rect1的时候初始化,之后不再初始化,不运行初始化代码
  • 静态成员变量具有记忆性,可以将上次实例化rect1时赋予静态变量的结果保存下来,作为下次实例化rec2的初值

static修饰的成员函数

static修饰的成员函数称为静态成员函数

静态成员函数和静态成员变量类似,所有对象所共享,可以类内定义也可以类外定义,可以使用::来调用,最重要的是非静态成员函数没有this指针,因此静态成员函数不能访问非静态成员函数和非静态数据成员,因为没有this指针静态成员函数不知道这个非静态成员变量到底是属于哪个对象的

总的来说:

 

1.静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数。

 

2.非静态成员函数可以任意的访问静态成员函数和静态数据成员。

 

3.静态成员函数不能访问非静态成员函数和非静态数据成员。

参考文章:

(103条消息) c++中的static详解_c++ static_大楠树的博客-CSDN博客

值得注意的是静态成员函数,静态成员变量,非静态成员函数均只有一份,不占用类的内存,那么非静态成员函数怎么知道谁在调用它呢,答案是使用this指针,也就是说谁调用这个函数this指针就指向谁

const

与static讨论的是作用域生命周期以及存储的问题不同的是const主要讨论的是访问权限的问题,即只读

const不考虑类的情况

const常量必须显示初始化,初始化后不可更改

非const类型可以转换成const类型

const考虑类的情况

const成员变量

  • const成员变量必须通过初始化列表进行初始化(const成员变量,引用,没有提供默认构造函数的类类型必须通过初始化列表进行初始化)
  • 每个实例化对象都有它们自己const成员变量

常函数

首先理解下this指针,this指针本质是一个指针常量,它只能指向当前调用这个成员函数的实例化对象,此时它的指向不可以更改,(this指针不算类的数据成员,它相当于是成员函数默认隐含的第一个参数,每当一个对象调用成员函数则将对象的地址(可能不是地址就只是偏移量)传递给this)下面的程序类似的解释了this的原理。

 

 1 class Person {
 2 public:
 3 
 4     int m_ = 10;
 5 };
 6 void fun(Person* const _this) {
 7 
 8 }
 9 int main()
10 {
11     Person p1;
12     Person p2;
13     fun(&p1);
14     fun(&p2);
15     system("pause");
16     return 0;
17 }

 

 

 

 

如果是常函数则它的this指针是const *const类型的那么除了它的指向不可以修改,它指向成员变量的值也不可以修改,也就是说不可以在常函数内部修改普通的成员变量

 但是常函数内部可以修改mutable修饰的成员变量

 常对象修改mutable修饰的成员变量,可以修改静态成员变量,只能调用常函数

普通对象不能修改const修饰的成员变量,其他都可以修改和调用

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Person {
 5 public:
 6     Person(int h) :h_(h) {
 7 
 8     }
 9     int m_ = 10;
10     const int h_;
11     mutable int n_ = 20;
12     static int y_;
13     void fun() {
14 
15     }
16     void func()const {
17 
18     }
19 };
20 int Person::y_ = 40;
21 int main()
22 {
23     const Person p1(3);
24     p1.m_ = 20;//错误
25     p1.h_ = 30;//错误
26     p1.n_ = 40;
27     p1.y_ = 50;
28     p1.fun();//错误
29     p1.func();
30     Person p2(4);
31     p2.m_ = 20;
32     p2.h_ = 30;//错误
33     p2.n_ = 40;
34     p2.y_ = 50;
35     p2.fun();
36     p2.func();
37     system("pause");
38     return 0;
39 }

 

标签:const,函数,静态,成员,static,变量
From: https://www.cnblogs.com/Sandals-little/p/17575320.html

相关文章

  • 10.define和const的区别
    define生效于编译预处理阶段,const生效于编译阶段define只是简单的字符串替换,在编译预处理阶段将所有用到宏的地方进行字符串替换,没有进行数据类型检查;const有数据类型,编译器要对其进行类型检查define不分配内存,而const在静态区分配内存,因此define没有地址,不可以使用指针指......
  • C++Const变量的存储位置
    const变量/对象的存储位置const局部变量const局部基础变量和自定义变量都存储在栈上structdiy_class{inta;intb;diy_class(inta,intb):a(a),b(b){}};intmain(){intb=1;//这个肯定在栈上constinta=10;//比较ab两个变......
  • 轻松理解Java中的public、private、static和final
    一、概念1、public和private两个都是访问权限修饰符,用于控制外界对类内部成员的访问。public:表明对象成员是完全共有的,外界可以随意访问。用public修饰的数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用。private:表明对象成员是完全私有的,不容许外界的任何......
  • android studio Attribute value must be constant
    解决"androidstudioAttributevaluemustbeconstant"错误的步骤当我们在使用AndroidStudio开发应用程序时,有时会遇到"Attributevaluemustbeconstant"的错误。该错误通常发生在我们尝试在XML布局文件中设置属性的值时。下面是解决该错误的步骤,以及每个步骤需要做......
  • (GCC) gcc编译选项 -Wl, -start-group,whole-archive,-Wl, Bstatic
    1.start-group编译选项假设程序x依赖三个静态库:libX1.a、libX2.a和libX3.a,而libX2.a又依赖libX1.a,libX3.a依赖libX2.a和libX1.a,正常情况下的CMakeLists.txt格式如下target_link_libraries(xlibX1.alibX2.alibX3.a)但也可以偷懒,不关心静态库的顺序问题,ld......
  • 【八股文 01】const 关键字
    1const含义被它修饰的值不能改变,是只读变量。必须在定义的时候就给它赋初值2const作用1、修饰变量,说明该变量不可以被改变2、修饰指针,分为指向常量的指针(pointertoconst)和自身是常量的指针(常量指针,constpointer)和前面两种的组合:指向常量的常指针3、修饰引用,指向常量的......
  • 关于@RequiredArgsConstructor使用
    1.Lombok官方解释:@RequiredArgsConstructor为每个需要特殊处理的字段生成一个具有1个参数的构造函数。所有未初始化的final字段都会获取一个参数,以及标记为@NonNull的任何字段,这些字段在声明它们的位置未初始化。对于那些标有@NonNull的字段,还会生成显式空检查。如果用于标......
  • c语言static关键字的用法
    今天的c语言学习中遇到了static关键字,由于对这个关键字的用法比较模糊,但是这个关键字的作用很大,以下是它的用法:一、修饰局部变量(1)用静态关键字static修饰的局部变量,在编译的过程中,会在数据区为该变量开辟空间,并对其进行初始化,如果代码中未对其进行初始化,则系统默认初始化......
  • python中的@classmethod和@staticmethod的作用
    classA(object):bar=1deffunc1(self):print("foo")@classmethoddeffunc2(cls):print("func2")print(cls.bar)cls().func1()A.func2()@classmethod的作用实际时可以在class内部实例化class。作用就是比u输......
  • const 常量与常量
    const常量与常量在C语言中,通过内联方式直接写到源代码中的字面量值一般被称为“常量”。比如这里的-10,‘c’,2.0。intx=-10;chary='c';doublez=2.0;还有一种常量,是用const关键字按照与定义变量相同语法定义的量。比如:constintvx=10;constint*p......