C++ -- 学习系列 static 关键字的使用

这篇具有很好参考价值的文章主要介绍了C++ -- 学习系列 static 关键字的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

static 是 C++ 中常用的关键字,被 static 修饰的变量只会在 静态存储区(常量数据也存放在这里) 被分配一次内存,生命周期与整个程序一样,随着程序的消亡而消亡。

一  static 有以下几种用法:

1. 在文件中定义的 静态全局变量

2. 在函数中定义的静态变量

3. 类的静态成员变量

4. 静态类对象

5. 类的静态方法

1. 在文件中定义的 静态全局变量

// main.cpp
#include<iostream>

int  xxx = 66; 

static int yyy = 888;

int main()
{
   std::cout << xxx << std::endl;
   std::cout << xxx << std::endl;
   
   return ;
}
  • 全局变量特点:

全局变量默认是有外部链接性的,作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过 extern 全局变量名的声明,就可以使用全局变量。

  • 静态全局变量特点:

全局静态变量是显式用 static 修饰的全局变量,作用域是声明此变量所在的文件,其他的文件即使用 extern 声明也不能使用。

2. 在函数中定义的静态局部变量

在函数中定义的静态变量仅仅初始化一次,且变量会存储到静态存储区,因此即便离开函数作用域也不会消失。

// c.h
#include<iostream>
#include<string>

class C
{
public:
    C(std::string n):name(n)
    {
        std::cout << "constructor C " << std::endl;
    }
    ~C(){
        std::cout << "destructor C " << std::endl;
    }

    std::string  getName()
    {
        return this->name;
    }

private:
    std::string name;
};


// main.cpp

#include<iostream>
#include"c.h"

void  testStatic()
{
   static  int  count = 0;  // 只会被初始化一次
   cout << "count: " << count++ << endl; // 每次调用该函数都会将上次存储的值打印出来
}

C& getTestStaticC()
{
    static C c("I'm static object."); // 只初始化一次,生命周期与程序等长

    return c;
}


int main()
{

    testStatic();
    testStatic();
    testStatic();

    C& cc1 = getTestStaticC(); // 因为定义的静态变量存储在静态存储区,不是在栈上,因此离开函数作用域以后,对静态的引用仍然是可以访问的
    C& cc2 = getTestStaticC(); // 因为定义的静态变量存储在静态存储区,不是在栈上,因此离开函数作用域以后,对静态的引用仍然是可以访问的

    std::cout << "cc1: " << cc1.getName() << std::endl;
    std::cout << "cc2: " << cc2.getName() << std::endl;
    C  cc3("666888");

    return 0;
}


输出:

C++ -- 学习系列 static 关键字的使用,c++,学习,开发语言

3. 类的静态成员变量

类的静态成员变量属于类的所有对象,其存储在静态存储区,只有一个存储空间;而其他的非静态变量属于每个对象,在每个对象中都有其副本。

静态成员变量不在构造函数中初始化,因此静态成员变量不依赖于对象。

静态成员变量必须显示的初始化,一般情况下,我们都在类的外部对静态成员变量初始化,若是静态成员变量未被初始化,编译链接时,会报错。

// c.h
#include<iostream>
#include<string>

class C
{
public:
    C(std::string n):name(n)
    {
        std::cout << "constructor C name: " << this->name << std::endl;
    }
    ~C(){
        std::cout << "destructor C name: " << this->name << std::endl;
    }

    std::string  getName()
    {
        return this->name;
    }


private:
public:
    std::string name;
    static int height;
};


// c.cpp
#include "c.h"

int C::height = 66; // 静态成员变量需要显示的定义在类的外部


// main.cpp
#include"c.h"
#include<iostream>

int& testStatic21()
{
    C c("static21 test");
    std::cout << "name: " << c.getName() << " , height: " << c.height << std::endl;

    return c.height;
}
std::string& testStatic22()
{
    C c("static22 test");
    std::cout << "name: " << c.getName() << " , height: " << c.height << std::endl;

    return c.name;
}

int main()
{
    int& abc = testStatic21();

    std::cout << "abc: " << abc << std::endl; // 因为存储在静态存储区,所以离开函数作用域后,变量仍然存在

    std::string& name = testStatic22();
    std::cout << "name: " << name << std::endl; // 非静态成员变量实际存储位置是函数的栈空间中,因此离开函数作用域后,就会被释放掉,所以获取结果未可知

  return 0;
}

输出:

C++ -- 学习系列 static 关键字的使用,c++,学习,开发语言

4. 静态类对象

static 关键字对类对象的工作方式也相同。声明为 static 的对象将分配到静态存储区中,并且一直作用到程序结束。

注:使用 static 关键字分配为零仅适用于原始数据类型,不适用于用户定义的数据类型。

// c.h
#include<iostream>
#include<string>

class C
{
public:
    C(std::string n):name(n)
    {
        std::cout << "constructor C name: " << this->name << std::endl;
    }
    ~C(){
        std::cout << "destructor C name: " << this->name << std::endl;
    }

    std::string  getName()
    {
        return this->name;
    }


private:
public:
    std::string name;
};


// main.cpp
int main()
{
   C& cc = testStatic3();

   std::cout << "cc: " << cc.getName() << std::endl; // 静态对象存储在静态存储区, 所以离开函数作用域后,仍然存在

  return 0.
}

输出:

C++ -- 学习系列 static 关键字的使用,c++,学习,开发语言

5. 类的静态方法

与类的静态成员变量类似,类的静态方法也属于类,任何类的对象都可以调用此类方法。

既可以通过 对象名. 静态方法 调用,也可以通过类名::静态方法,后一种方法更常用。

// c.h
#include<iostream>
#include<string>

class C
{
public:
    C(std::string n):name(n)
    {
        std::cout << "constructor C name: " << this->name << std::endl;
    }
    ~C(){
        std::cout << "destructor C name: " << this->name << std::endl;
    }

    std::string  getName()
    {
        return this->name;
    }

    static void print()
    {
        std::cout << "print height: " << height << std::endl;
    }



private:
public:
    std::string name;

    static int height;
};

// c.cpp
#include "c.h"


int C::height = 66;


// main.cpp
#include"c.h"
#include<iostream>

void testStatic4()
{
    C::print();
    C c("888");
    c.print();
}

int main()
{
  testStatic4();

  return 0;
}

二    static 变量几种初始化方式

C++中static变量的初始化_c++ static 重新初始化_LikeMarch的博客-CSDN博客

三种初始化:

1. 编译时初始化

2. 程序加载时初始化

3. 运行时初始化

1. 编译时初始化

若 静态全局变量 是 基本数据类型(POD) ,且初始化值为常量,那么该变量会在编译期初始化。

/ main.cpp

static int xx = 666;

int main()
{

   return 0;
}

2. 程序加载时初始化

程序被加载时立即初始化,该过程发生在main 函数执行前。即使程序任何地方都没访问过该变量,仍然会进行初始化,因此形象地称之为"饿汉式初始化"。

2.1  静态全局变量初始化(初始值不是常量时),此时变量初始化是在程序加载时初始化的。

// main.cpp

int x = 6;
int y = 8;
static int z = x + y;

int main()
{

  return 0;
}

2.2  静态全局变量不是基本类型,此时变量初始化是在程序加载时初始化的。

// d.h
#include<iostream>
#include<string>

class D
{
public:
    D(std::string n):name(n)
    {
        std::cout << "constructor D name: " << this->name << std::endl;
    }
    ~D()
    {
        std::cout << "destructor D name: " << this->name << std::endl;
    }

private:
    std::string name;
};

// c.h
class C
{
public:
    C(std::string n):name(n)
    {
        std::cout << "constructor C name: " << this->name << std::endl;
    }
    ~C(){
        std::cout << "destructor C name: " << this->name << std::endl;
    }

    std::string  getName()
    {
        return this->name;
    }

    static void print()
    {
        std::cout << "print height: " << height << std::endl;
    }



private:
public:
    std::string name;

    static int height;
    static D d;
};

// c.cpp
int C::height = 66;

D C::d = D("CD static");

// main.cpp
#include<string>
#include<iostream>
#include"c.h"

void testStatic5()
{
    C c("testStatic5 -- ");
    std::cout << "testStatic5 c name: " << c.getName() << std::endl;
}

static D d("before main inialiaze!");

int main()
{

  std::cout << "enter int main func!!" << std::endl;
  testStatic5();

  return 0;
}

C++ -- 学习系列 static 关键字的使用,c++,学习,开发语言

3. 运行时初始化

程序执行到静态变量的定义引用时,才会初始化,因此也被称为“懒汉式初始化”。

比如静态局部变量就是典型的 运行时初始化。

// d.h
class D
{
public:
    D(std::string n):name(n)
    {
        std::cout << "constructor D name: " << this->name << std::endl;
    }
    ~D()
    {
        std::cout << "destructor D name: " << this->name << std::endl;
    }

public:
    std::string name;
};


// main.cpp

#include<iostream>
#include"d.h"


void testStaticInitialize(){
    static D d("testStaticInitialize --- ");
}

int main()
{
  std::cout << "enter int main func!!" << std::endl;
  static D dd("dd --- ");
  testStaticInitialize();

  return 0;
}

输出:

C++ -- 学习系列 static 关键字的使用,c++,学习,开发语言文章来源地址https://www.toymoban.com/news/detail-705797.html

到了这里,关于C++ -- 学习系列 static 关键字的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】static 关键字的特性 与 问题

    声明为 static的类成员 称为 类的静态成员 用 static 修饰的成员变量 ,称之为 静态成员变量 ; 用 static 修饰的成员函数 ,称之为 静态成员函数 。 静态成员变量 一定要在 类外进行初始化 。 下面一段代码证明 上述定义: 输出结果: 从代码可以看出,静态成员变量需要在 类

    2024年02月14日
    浏览(33)
  • 在C++和C中static关键字的用法,在C++和C中const关键字的用法

    1、在C++和C中static的用法 答:static表示存储类型,修饰数据类型。在C语言中,static修饰局部变量,内存分配在静态区,生命周期延长,作用域不变。static修饰全局变量,内存分配在静态区,作用域被局限于本文件,不能被extern引用。static修饰函数,不能被exter

    2024年02月10日
    浏览(30)
  • C++——初始化列表 | explicit关键字 | static成员

    🌸作者简介: 花想云 ,在读本科生一枚,致力于 C/C++、Linux 学习。 🌸 本文收录于 C++系列 ,本专栏主要内容为 C++ 初阶、C++ 进阶、STL 详解等,专为大学生打造全套 C++ 学习教程,持续更新! 🌸 相关专栏推荐: C语言初阶系列 、 C语言进阶系列 、 数据结构与算法 本章我们

    2023年04月11日
    浏览(40)
  • 【C++】const、static关键字和构造函数初始化

    💗个人主页💗 ⭐个人专栏——C++学习⭐ 💫点击关注🤩一起学习C语言💯💫 目录 1. const修饰成员函数 1.1 语法格式 1.2 权限放大缩小 1.3 思考 1.4 解答 2. 再谈构造函数 2.1 构造函数体赋值 2.2 初始化列表 2.3 explicit 3. static成员 3.1 静态变量 3.2 静态函数 3.3 静态成员变量

    2024年02月19日
    浏览(38)
  • 深入理解C++中的静态(Static)关键字及其应用场景

    在C++中,静态(Static)是一个常见且重要的概念,用于描述变量、函数和类成员。它具有独特的特性和作用域,可以在不同的应用场景中发挥重要作用。本文将详细讨论C++中的静态,包括静态变量、静态函数和静态类成员,并对其与全局变量之间的区别进行分析

    2024年02月09日
    浏览(34)
  • C++面试八股文:static和const的关键字有哪些用法?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第7面: 面试官:C++中, static 和 const 的有哪些用法? 二师兄: satic 主要用在以下三个方面:1.用在全局作用域,修饰的变量或者函数为静态的,限制在本文件内使用。2.方法内修饰修饰静态局部变量,在第一次访问

    2024年02月08日
    浏览(37)
  • 面向对象(八)-- static 与 final 关键字 的使用

    目录 1.  static 1.1  static 的概述 1.2  static 修饰的特点 1.3  static 使用时的注意事项:

    2023年04月25日
    浏览(30)
  • 第1关:学习-Java类和对象之static关键字之求圆环面积和周长

    本关任务:已知圆环的大圆半径 R 和 小圆半径 r 的长度分别为 32.0 和 10.0,求该圆环的面积和周长。 圆环面积公式为:S=π(R 2−r 2 ); 圆环周长公式为:C=2π(R+r)。 /** 任务:已知圆环的大圆半径 R 和 小圆半径 r 的长度分别为 32.0 和 10.0,求该圆环的面积和周长。 类名为:Ri

    2023年04月08日
    浏览(31)
  • C/C++ static关键字详解(最全解析,static是什么,static如何使用,static的常考面试题)

    目录 一、前言  二、static是什么? 三、static修饰的对象是什么?   四、C 语言中的 static  🍎static的C用法  🍉static的重点概念  🍐static修饰局部变量  💦static在修饰局部变量和函数的作用  🍓static修饰全局变量和函数 💦static在修饰全局变量和函数的作用

    2024年02月05日
    浏览(37)
  • static关键字和final关键字

    在java的中,static和final是两个必须掌握的。static和final用法多样,且在一定环境下使用,可以提高程序的运行性能,优化程序的结构。下面将依次介绍static和final。注意,某些场景下,staic和final可以联合使用

    2024年02月09日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包