从零开始学C++之对象的使用(二):四种对象生存期和作用域、static 用法总结

一、四种对象生存期和作用域

栈对象

隐含调用构造函数(程序中没有显式调用)

堆对象

隐含调用构造函数(程序中没有显式调用),要显式释放

全局对象、静态全局对象

全局对象的构造先于main函数 已初始化的全局变量或静态全局对象存储于.data段中 未初始化的全局变量或静态全局对象存储于.bss段中

静态局部对象

已初始化的静态局部变量存储于.data段中 未初始化的静态局部变量存储于.bss段中

#include <iostream>
using namespace std;

class Test
{
public:
    Test(int n) : n_(n)
    {
        cout << "Test " << n_ << " ..." << endl;
    }
    ~Test()
    {
        cout << "~Test " << n_ << " ..." << endl;
    }
private:
    int n_;
};

int n;          // 未初始化的全局变量,初始值为0。n存储于.bss段中。(block started by symbol)
int n2 = 100;   // 已初始化的全局变量,初始值为100。n2存储于.data段中。
Test g(100);        // 全局对象的构造先于main函数
static Test g2(200);

int main(void)
{
    cout << "Entering main ..." << endl;

    Test t(10);     // 栈上创建的对象,在生存期结束的时候自动释放
    {
        Test t(20);
    }

    {
        Test *t3 = new Test(30);        // 堆上创建的对象,要显式释放
        delete t3;
    }

    {
        static int n3;          // n3存储于.bss段中      (编译期初始化)
        static int n4 = 100;    // n4存储于.data段中 (编译期初始化)

        static Test t4(333);    // t4对象运行期初始化   .data段
    }
    cout << "Exiting main ..." << endl;
}

二、static 用法总结

1. 用于函数内部修饰变量,即函数内的静态变量。这种变量的生存期长于该函数,使得函数具有一定的“状态”。使用静态变量的函数一般是不可重入的,也不是线程安全的,比如strtok(3)。

2. 用在文件级别(函数体之外),修饰变量或函数,表示该变量或函数只在本文件可见,其他文件看不到也访问不到该变量或函数。专业的说法叫“具有internal linkage”(简言之:不暴露给别的translation unit)。 C语言的这两种用法很明确,一般也不容易混淆。

由于C++引入了类,在保持与C语言兼容的同时,static关键字又有了两种新用法:

3.用于修饰类的数据成员,即所谓“静态成员”。这种数据成员的生存期大于class的对象(实例/instance)。静态数据成员是每个class有一份,普通数据成员是每个instance 有一份。

4. 用于修饰class的成员函数,即所谓“静态成员函数”。这种成员函数只能访问静态成员和其他静态成员函数,不能访问非静态成员和非静态成员函数。

参考:

C++ primer 第四版 Effective C++ 3rd C++编程规范

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术专栏

Python3入门与实践(四): 面向对象

==当通过 student.name获取变量值的时候,首先会查找实例变量里有没有name属性,如果有则返回,如果没有就会去类变量里找,如果还是没有则会报错==

692
来自专栏前端学习心得

JavaScript中数据类型

1233
来自专栏java一日一条

深入浅出JavaScript之this

JavaScript中的this比较灵活,根据在不同环境下,或者同一个函数在不同方式调用下,this都有可能是不同的。但是有一个总的原则,那就是this指的是,...

352
来自专栏java学习

面试题67(以下程序创建了几个对象——String)

面试例题1:以下程序创建了几个对象? String A,B, C; A="a"; B="b"; A=A+B; StringBuffer D=new String...

2627
来自专栏编程坑太多

python--面向对象与模块补充,反射

1554
来自专栏抠抠空间

函数 (二) 名称空间与作用域

一、什么是名称空间 我们写一段代码,里面肯定会定义一些变量名,函数名,而一旦我们运行代码,python解释器在加载这些代码的时候,会在内存中开辟一片空间专门用来...

31810
来自专栏木子昭的博客

JS数据类型转换规则显示类型转换

JS数据类型 基础类型 String Boolean Number Symbol Undefine Null(typeof(null) === "object...

3215
来自专栏noteless

[四] java虚拟机JVM编译器编译代码简介 字节码指令实例 代码到底编译成了什么形式

前文已经对虚拟机进行过了简单的介绍,并且也对class文件结构,以及字节码指令进行了详尽的说明

1112
来自专栏前端大白专栏

Object.keys()具体使用方式

1465
来自专栏Python小屋

Python扩展库numpy中where()函数的三种用法

第二种用法:给where()函数传递一个包含True/False值的数组,返回该数组中True值的下标,结合numpy数组的关系运算,可以返回数组中符合特定条件...

904

扫码关注云+社区