文档章节

常量变量的生命周期及声明方式

晷骥
 晷骥
发布于 2017/07/21 18:07
字数 833
阅读 74
收藏 0

##原生数据类型 POD的静态变量##

  1. 静态成员初始化与一般数据成员初始化不同。

    静态成员变量在类里面声明的时候无法直接初始化,需要在类体外部进行初始化,格式如下:

    <数据类型> <类名>::<静态数据成员名>=<值>

     class Test {
     public:
         static int arg1;
     private :
         static int arg2;
     };
    
     int Test::arg1 = 1;
     int Test::arg2 = 2;
    

    初始化的时候不区分public或者private

  2. 常量成员变量及静态常量成员变量的初始化

    • 常量成员变量和静态常量成员变量可以在声明的时候进行初始化
    • 常量成员变量可以在构造的时候进行初始化
    • 静态常量成员变量可以在类体外和静态成员变量一样进行初始化

    示例代码如下:

         class Test {
         public:
             Test() : arg6(6) {}
         public :
             const int arg5 = 5;
             const int arg6;
    
         private :
             const static int arg3 = 3;
             const static int arg4;
         };
         const int Test::arg4 = 4;
    

##静态变量的生命周期##

###常量变量有以下几类:###

  1. 全局常量变量

  2. 命名空间内的常量变量

  3. 类的常量变量

  4. 函数体内的常量变量

对于以上 1/2/3类的静态变量,在程序启动时进行初始化,在程序结束时释放

对于函数体内的静态变量,在第一次执行到该static变量的定义时创建,在程序结束时释放;如果程序一直没执行到该static变量的定义,则一直不会创建,也当然不会释放

###测试分析###

  1. 全局常量变量和命名空间内的常量变量

     class A {
     public:
         A() { cout << "A()" << endl; }
         ~A(){ cout << "~A()" << endl; }
     };
    
     A a;
    
     namespace test {
         class B {
         public:
             B() { cout << "B()" << endl; }
             ~B(){ cout << "~B()" << endl; }
         };
         B b;
     }
    
     int main()
     {
         cout << "main begin" << endl;
         cout << "main end" << endl;
         return 0;
     }
    

    输出:

     A()
     B()
     main begin
     main end
     ~B()
     ~A()
    

    如果把A a的定义放到B b的后面,则输出会变为

     B()
     A()
     main begin
     main end
     ~A()
     ~B()
    

    如果静态常量A和B分别定义在不同的头文件,在庞大的工程中,构建的顺序难以确定,此时静态变量的构造函数、析构函数和初始化的顺序在 C++ 中是不确定的,甚至随着构建变化而变化,导致难以发现的 bug. 所以除了禁用类类型的全局变量,我们也不允许用函数返回值来初始化 POD 变量,除非该函数不涉及(比如 getenv() 或 getpid())不涉及任何全局变量。(函数作用域里的静态变量除外,毕竟它的初始化顺序是有明确定义的,而且只会在指令执行到它的声明那里才会发生。

  2. 类中的常量变量 class A { public: A() { cout << "A::A()" << endl; } ~A() { cout << "A::~A()" << endl; } };

     class B
     {
         static A a;
     };
    
     A B::a;
    
     int main(int argc, char* argv[])
     {
         cout << "main begin" << endl;
         system("pause");
         cout << "main end" << endl;
         return 0;
     }
    

    输出:

     A::A()
     main begin
     main end
     A::~A()
    
  3. 函数中的常量变量

     class A
     {
     public:
         A() { cout << "A::A()" << endl; }
         ~A() { cout << "A::~A()" << endl; }
     };
    
     void func()
     {
         cout << "func start" << endl;
         static A a;
         cout << "func end" << endl;
     }
    
     int main(int argc, char* argv[])
     {
         cout << "main begin" << endl;
         func();
         system("pause");
         cout << "main end" << endl;
         return 0;
     }
    

    输出:

     main begin
     func start
     A::A()
     func end
     main end
     A::~A()
    

    如果不调用func(),则不会输出A::A()和A::~A()

© 著作权归作者所有

上一篇: 将博客搬至CSDN
下一篇: 谷歌C++编码规范
晷骥
粉丝 0
博文 3
码字总数 845
作品 0
厦门
程序员
私信 提问
C++中引用和匿名对象的理解和本质剖析

大家对C++的引用应该都不陌生吧,抱着既要知其然,也要知其所以然的态度。 下面将按照是什么?怎么用?为什么需要?本质剖析的流程来想大家一一描述。 引用时什么? 引用其实就是给变量起的一...

沙米笔记
2016/04/10
3.4K
24
c# constant 和 static readonly的区别

修饰符 可修饰的变量 初始化位置 不变性 生命周期 constant 基本类型 声明的时候初始化 编译时常量 编译器存入变量metadata中,使用时不需要加载到ram static readonly 不限 声明+构造器 运行...

holysu
2017/09/05
0
0
类加载以及变量生命周期分析

类加载以及变量生命周期分析 明确初始化过程以及变量生命周期对于内存优化以及高并发有重要意义,比如哪些变量需要声明成为类变量,哪些可以是局部变量,有效避免向前引用及线程安全等。 一、...

wow863597
2016/07/03
26
0
CSharp初级篇 1-4 this、索引器、静态、常量以及只读

.NET Core CSharp初级篇 1-4 本节内容为this、索引器、静态、常量以及只读 简介 在之前的课程中,我们谈论过了静态函数和字段的一小部分知识,本节内容中,我们将详细的讲解关于对象操作的例...

WarrenRyan
07/20
0
0
iOS正确使用const,static,extern

static 修饰局部变量 让局部变量只初始化一次 局部变量在程序中只有一份内存 并不会改变局部变量的作用域,仅仅是改变了局部变量的生命周期(只到程序结束,这个局部变量才会销毁) 修饰全局...

Daniel_s
2016/11/21
16
0

没有更多内容

加载失败,请刷新页面

加载更多

搭建高可用MongoDB集群(分片)

搭建高可用MongoDB集群(分片) MongoDB基础请参考:https://blog.51cto.com/kaliarch/2044423 MongoDB(replica set)请参考:https://blog.51cto.com/kaliarch/2044618 一、概述 1.1 背景 ......

linjin200
22分钟前
5
0
CDH6.0.1集成tez-0.9.1计算引擎

参考文章: https://www.jianshu.com/p/9fb9f32e1f0f https://www.baidu.com/link?url=OgpwasnZi7H1dySN2T111sseEWDBaCCTC3DFV61G7756YbrkJCA8Y3UFaueyqnfN&wd=&eqid=daeb8b3500049cf3000000......

Sheav
24分钟前
4
0
Vue内置指令的使用

v-model(数据绑定) v-model常用于表单数据的双向绑定,它本质上是一个语法糖。它主要的有两种应用: 在文本框、多行文本、input的下拉框、单选按钮、复选框中的应用 <div id="app"> ...

凌兮洛
24分钟前
5
0
外部来源应用检查-烦死了,终于找到解决设置了

Android 连接usb调试应用的时候: 华为关闭方法:1、设置-安全-更多安全设置,关掉外部来源应用检查。2、设置-系统-开发人员选项-关闭“监控ADB安装应用” 不知道OPPO 怎么关闭的?...

QGlaunch
25分钟前
4
0
6个K8s日志系统建设中的典型问题,你遇到过几个?

作者 | 元乙 阿里云日志服务数据采集客户端负责人,目前采集客户端 logtail 在集团百万规模部署,每天采集上万应用数 PB 数据,经历多次双 11、双 12 考验。 导读:随着 K8s 不断更新迭代,使...

阿里云官方博客
27分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部